第 05 章

Pull Request、Issue 與 Branch

真實的團隊開發不會只有一條線性歷史。Branch 讓你平行開發,Issue 追蹤問題,Pull Request 進行程式碼審查——這三個功能構成了 GitHub 協作的核心。

Branch(分支)

Branch 是 Git 中最強大的功能之一。它讓你在不影響主線程式碼的情況下,獨立開發新功能或修正 bug。

Branch 是什麼?

在 Git 中,分支其實只是一個指向某個 commit 的指標(一個 40 字元的 SHA-1 存在 .git/refs/heads/ 中)。建立分支幾乎是瞬間完成的——不需要複製任何檔案。

gitGraph commit id: "C1" commit id: "C2" branch feature commit id: "C3" commit id: "C4" checkout main commit id: "C5"

分支操作指令

指令用途
git branch列出所有本地分支(* 號標示目前所在)
git branch <name>建立新分支(不切換)
git checkout <name>切換到指定分支
git checkout -b <name>建立並切換到新分支(最常用)
git switch <name>切換分支(Git 2.23+ 新指令)
git switch -c <name>建立並切換(Git 2.23+)
git branch -d <name>刪除已合併的分支
git branch -D <name>強制刪除分支(即使尚未合併)

分支操作實例

# 查看目前分支
$ git branch
* main

# 建立並切換到新分支
$ git checkout -b feature/add-login
Switched to a new branch 'feature/add-login'

$ git branch
  main
* feature/add-login
# 在分支上做修改
$ echo "<form>Login Form</form>" > login.html
$ git add login.html
$ git commit -m "feat: 新增登入頁面"

# 再做一筆修改
$ echo "form { margin: 20px; }" >> style.css
$ git add style.css
$ git commit -m "style: 登入表單樣式"

# 查看歷史
$ git log --oneline --graph --all
# 切回 main 分支
$ git checkout main

# 合併 feature 分支
$ git merge feature/add-login
Merge made by the 'ort' strategy.
 login.html | 1 +
 style.css  | 1 +
 2 files changed, 2 insertions(+)

# 刪除已合併的分支
$ git branch -d feature/add-login
Deleted branch feature/add-login (was c3a2f1b).

Merge(合併)

當分支上的工作完成後,需要把變更合併回主線。Git 有兩種主要的合併方式:

Fast-Forward Merge

如果主線在分支建立後沒有新的 commit,Git 直接把主線指標往前移動。不會產生額外的 merge commit。

flowchart LR C1 --> C2 --> C3 C3 --> C4["C4 (feature)"] C4 --> C5["C5 (feature)"] style C5 fill:#fde8e4
$ git merge feature
# Fast-forward → main 直接移到 C5

Three-Way Merge

如果主線也有新的 commit,Git 會找到兩個分支的共同祖先,建立一個新的 merge commit

flowchart LR C1 --> C2 C2 --> C3["C3 (main)"] C2 --> C4["C4 (feature)"] C3 --> M["Merge commit"] C4 --> M style M fill:#fde8e4
$ git merge feature
# Three-way merge → 建立 merge commit

Merge Conflict(合併衝突)

當兩個分支修改了同一個檔案的同一個位置,Git 無法自動決定要保留哪個版本,就會產生衝突。

# 衝突發生時,檔案中會出現標記
<<<<<<< HEAD
這是 main 分支的內容
=======
這是 feature 分支的內容
>>>>>>> feature/add-login

解決衝突的步驟:

  1. 打開有衝突的檔案,手動選擇要保留的內容。
  2. 刪除 <<<<<<<=======>>>>>>> 標記。
  3. git add <file> 標示衝突已解決。
  4. git commit 完成合併。

Pull Request(PR)

Pull Request 是 GitHub 上最重要的協作功能。它讓你在合併分支之前,請團隊成員審查你的程式碼。

PR 的完整流程

flowchart TD A["從 main 建立 feature 分支"] --> B["在 feature 分支上開發並 commit"] B --> C["git push origin feature"] C --> D["在 GitHub 上建立 Pull Request"] D --> E["團隊成員 Code Review"] E --> F{"審查通過?"} F -->|"需要修改"| G["繼續 commit 並 push"] G --> E F -->|"通過"| H["Merge PR"] H --> I["刪除 feature 分支"]

建立 PR 的操作

從命令列到 GitHub 的 PR 流程

# 建立分支並開發
$ git checkout -b feature/user-profile
$ echo "<div>Profile</div>" > profile.html
$ git add . && git commit -m "feat: 新增使用者個人頁面"

# 推送分支到 GitHub
$ git push origin feature/user-profile
  1. 在 GitHub Repo 頁面,會看到「Compare & pull request」按鈕。
  2. 填寫 PR 的標題與描述(說明你做了什麼、為什麼)。
  3. 指定 Reviewer(審查者)。
  4. 可以標記相關的 Issue(例如 Closes #12)。
  5. 點擊「Create pull request」。

審查者可以做的事:

  • Comment:針對特定程式碼行留下評論。
  • Approve:核准這個 PR。
  • Request Changes:要求修改後再審查。

PR 合併方式:

  • Merge commit:建立一個合併 commit(保留完整分支歷史)。
  • Squash and merge:把所有 commit 壓縮成一個(簡潔的歷史)。
  • Rebase and merge:將 commit 移到主線末端(線性歷史)。

Issue(議題追蹤)

Issue 是 GitHub 的議題追蹤系統,用來記錄 bug、功能需求、待辦事項或討論。

🐛 Bug 回報

描述問題的重現步驟、預期行為與實際行為,方便開發者定位問題。

✨ 功能需求

提出新功能的想法與需求,團隊可以在 Issue 中討論可行性。

📋 任務追蹤

用 Issue 作為待辦事項清單,搭配 Label 和 Milestone 管理進度。

Issue 的實用功能

功能說明
Label用標籤分類(如 bug、enhancement、documentation、good first issue)。
Assignee指派負責人。
Milestone將 Issue 歸入里程碑,追蹤階段性目標的進度。
Template建立 Issue 範本,統一回報格式。
關聯 PR在 PR 中寫 Closes #123,合併時自動關閉 Issue。

常見的分支策略

團隊開發需要約定分支的命名與使用規則。以下是兩種常見策略:

GitHub Flow(簡單版)

  • main 分支永遠可部署。
  • 每個功能或修正建立一個 feature 分支。
  • 完成後透過 PR 合併回 main。
  • 合併後刪除 feature 分支。
適合小團隊 持續部署

Git Flow(完整版)

  • main:正式發行版本。
  • develop:開發中的最新版本。
  • feature/*:功能開發分支。
  • release/*:版本發行準備。
  • hotfix/*:緊急修正。
適合大團隊 版本發行
建議:初學者先從 GitHub Flow 開始。等團隊規模成長、需要正式的版本發行流程時,再考慮 Git Flow。

🔧 動手練習

練習 1:Branch + Merge

# 建立分支
$ git checkout -b feature/about-page

# 新增檔案
$ echo "<h1>About</h1>" > about.html
$ git add . && git commit -m "feat: about 頁面"

# 合併回 main
$ git checkout main
$ git merge feature/about-page

# 刪除分支
$ git branch -d feature/about-page

練習 2:建立 PR

  1. 建立一個新分支並做一些修改。
  2. Push 到 GitHub。
  3. 在 GitHub 上建立 Pull Request。
  4. 自己試著審查並合併(或邀請同學互審)。

本章小結

知識重點

  • Branch 是指向 commit 的可移動指標,建立與切換都很快。
  • Merge 有 fast-forward 和 three-way 兩種方式。
  • Merge conflict 需要手動解決後再 commit。
  • Pull Request 是 GitHub 上進行程式碼審查與合併的標準流程。
  • Issue 是議題追蹤與專案管理的核心工具。
  • GitHub Flow 適合小團隊快速迭代。

下一章預告

  • 學習 rebase 重整提交歷史。
  • 理解 revertreset 的差異。
  • 使用 stash 暫存未完成的工作。
學習提示: Branch + PR 是現代軟體開發的標準工作流程。建議找一到兩位同學一起練習——一個人建立 PR,另一個人做 Code Review,互換角色,才能真正體會協作的感覺。