第 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
解決衝突的步驟:
- 打開有衝突的檔案,手動選擇要保留的內容。
- 刪除
<<<<<<<、=======、>>>>>>> 標記。
git add <file> 標示衝突已解決。
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
- 在 GitHub Repo 頁面,會看到「Compare & pull request」按鈕。
- 填寫 PR 的標題與描述(說明你做了什麼、為什麼)。
- 指定 Reviewer(審查者)。
- 可以標記相關的 Issue(例如
Closes #12)。
- 點擊「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
- 建立一個新分支並做一些修改。
- Push 到 GitHub。
- 在 GitHub 上建立 Pull Request。
- 自己試著審查並合併(或邀請同學互審)。
本章小結
知識重點
- Branch 是指向 commit 的可移動指標,建立與切換都很快。
- Merge 有 fast-forward 和 three-way 兩種方式。
- Merge conflict 需要手動解決後再 commit。
- Pull Request 是 GitHub 上進行程式碼審查與合併的標準流程。
- Issue 是議題追蹤與專案管理的核心工具。
- GitHub Flow 適合小團隊快速迭代。
下一章預告
- 學習
rebase 重整提交歷史。
- 理解
revert 與 reset 的差異。
- 使用
stash 暫存未完成的工作。