第三章:分支管理 – Git 最強大的武器

如果說 Git 有一個「殺手級功能」,那絕對是分支管理。在我十多年的開發生涯中,分支讓我能夠同時處理多個功能開發、修復緊急 bug,而且完全不會互相干擾。今天我們要深入了解這個讓 Git 如此強大的核心功能。

什麼是分支?

想像你正在寫一本小說,突然有了兩個不同的劇情走向想法。在傳統的寫作方式中,你可能需要複製整份文稿,分別發展兩個版本。但在 Git 的世界裡,分支就像是平行宇宙,你可以在不同的「時間線」上進行開發,最後再決定要合併哪些內容。

在技術層面上,分支其實就是一個指向特定提交的「標籤」。當你建立新分支時,Git 並沒有複製所有檔案,而是創建了一個新的指標,這就是為什麼 Git 的分支操作如此快速的原因。

分支的核心優勢

1. 隔離開發環境

每個功能在自己的分支上開發,不會影響主要程式碼:

# 主分支保持穩定
git switch main

# 在新分支開發功能
git switch -c feature-user-dashboard
# 在這裡可以自由實驗,不會影響 main

2. 平行開發

團隊成員可以同時開發不同功能:

# 張小明開發登入功能
git switch -c feature-login

# 李小華開發支付功能
git switch -c feature-payment

# 王小美修復 bug
git switch -c bugfix-header-layout

3. 實驗性開發

可以安全地嘗試新想法:

# 建立實驗分支
git switch -c experiment-new-algorithm

# 如果實驗失敗,直接刪除分支即可
git switch main
git branch -D experiment-new-algorithm

分支的基本操作

查看分支

# 查看本地分支
git branch

# 查看所有分支(包含遠端)
git branch -a

# 查看遠端分支
git branch -r

# 查看分支的詳細資訊
git branch -v

輸出範例:

* main
  feature-login
  feature-payment
  remotes/origin/main
  remotes/origin/develop

星號(*)表示目前所在的分支。

建立分支

# 建立新分支(但不切換)
git branch feature-new-feature

# 建立新分支並立即切換
git switch -c feature-new-feature

# 或使用傳統方式
git checkout -b feature-new-feature

# 從特定提交建立分支
git switch -c hotfix-critical HEAD~3

# 從其他分支建立分支
git switch -c feature-advanced develop

切換分支

# 使用新的 switch 指令(推薦)
git switch feature-login
git switch main

# 使用傳統的 checkout 指令
git checkout feature-login
git checkout main

# 切換到上一個分支
git switch -

# 創建並切換到新分支
git switch -c feature-user-profile

刪除分支

# 刪除已合併的分支
git branch -d feature-completed

# 強制刪除未合併的分支
git branch -D feature-experimental

# 刪除遠端分支
git push origin --delete feature-old

HEAD 指標的概念

HEAD 是 Git 中一個特殊的指標,它告訴 Git 你目前「站在哪裡」。想像 HEAD 就像是你在時間軸上的位置標記。

# 查看 HEAD 指向哪裡
git log --oneline -1

# 查看 HEAD 的詳細資訊
cat .git/HEAD

大部分時候,HEAD 指向某個分支的最新提交:

HEAD -> main -> a1b2c3d(最新提交)

但有時候 HEAD 也可能直接指向某個提交,這種狀態叫做 “detached HEAD”:

# 切換到特定提交(會進入 detached HEAD 狀態)
git checkout a1b2c3d

# 回到正常狀態
git switch main

分支策略

在實際開發中,不同的團隊會採用不同的分支策略。以下是三種最常見的策略:

Git Flow(適合大型專案)

這是最傳統但也最完整的分支策略:

# 主要分支
main        # 生產環境程式碼
develop     # 開發環境整合分支

# 支援分支
feature/    # 功能開發分支
release/    # 版本發布分支
hotfix/     # 緊急修復分支

實際操作範例:

# 開發新功能
git switch develop
git pull origin develop
git switch -c feature/user-authentication

# 功能完成後
git switch develop
git merge feature/user-authentication
git push origin develop
git branch -d feature/user-authentication

GitHub Flow(適合小型團隊)

這是簡化版的策略,只有兩種分支:

main           # 主分支,隨時可部署
feature/*      # 功能分支

實際操作範例:

# 開發新功能
git switch main
git pull origin main
git switch -c feature/payment-integration

# 通過 Pull Request 合併回 main

GitLab Flow(平衡型策略)

結合前兩者的優點:

main           # 主要開發分支
production     # 生產環境分支
feature/*      # 功能分支

分支命名規範

好的分支命名讓團隊協作更順暢:

推薦的命名格式

# 功能開發
feature/user-login
feature/payment-system
feature/admin-dashboard

# Bug 修復
bugfix/header-alignment
bugfix/memory-leak-issue
fix/login-validation

# 緊急修復
hotfix/security-patch
hotfix/payment-gateway-down

# 實驗性功能
experiment/new-ui-framework
spike/performance-optimization

# 版本發布
release/v1.2.0
release/2024-q1

命名最佳實踐

  1. 使用小寫字母和連字符
# 好的命名
feature/user-profile
bugfix/login-error

# 避免的命名
Feature/UserProfile
bugfix_login_error
  1. 包含簡短的描述
# 清楚明瞭
feature/shopping-cart
hotfix/payment-timeout

# 過於模糊
feature/stuff
fix/bug
  1. 包含票號或任務編號
# 如果使用任務管理系統
feature/JIRA-123-user-registration
bugfix/TICKET-456-memory-leak

實際的分支操作範例

讓我們模擬一個真實的開發場景:

場景:開發一個使用者登入功能

# 1. 確保主分支是最新的
git switch main
git pull origin main

# 2. 建立功能分支
git switch -c feature/user-login

# 3. 開始開發,建立登入頁面
touch login.html login.js login.css
git add .
git commit -m "建立登入頁面基本結構"

# 4. 實作登入邏輯
echo "function login() { /* 登入邏輯 */ }" > login.js
git add login.js
git commit -m "實作使用者登入驗證邏輯"

# 5. 新增樣式
echo "/* 登入頁面樣式 */" > login.css
git add login.css
git commit -m "完成登入頁面樣式設計"

# 6. 推送分支到遠端
git push -u origin feature/user-login

# 7. 功能完成,合併回主分支
git switch main
git pull origin main
git merge feature/user-login

# 8. 推送合併後的主分支
git push origin main

# 9. 清理本地分支
git branch -d feature/user-login

# 10. 清理遠端分支(可選)
git push origin --delete feature/user-login

場景:緊急修復生產環境 Bug

# 1. 從主分支建立緊急修復分支
git switch main
git pull origin main
git switch -c hotfix/login-crash

# 2. 快速修復
echo "fixed login crash issue" > fix.patch
git add .
git commit -m "修復登入頁面崩潰問題"

# 3. 立即合併並部署
git switch main
git merge hotfix/login-crash
git push origin main

# 4. 如果有開發分支,也要合併過去
git switch develop
git merge hotfix/login-crash
git push origin develop

# 5. 清理分支
git branch -d hotfix/login-crash

分支管理的最佳實踐

1. 保持分支的目的單一

# 好的做法:每個分支只做一件事
git switch -c feature/add-search-function
git switch -c bugfix/fix-navbar-responsive

# 避免的做法:在一個分支做多件事
git switch -c feature/search-and-bugfixes-and-refactor

2. 定期同步主分支

# 在功能分支上定期同步主分支的變更
git switch feature/user-profile
git fetch origin
git merge origin/main

# 或使用 rebase(保持線性歷史)
git rebase origin/main

3. 及時清理無用分支

# 查看已合併的分支
git branch --merged

# 刪除已合併的本地分支
git branch --merged | grep -v "main\|develop" | xargs -n 1 git branch -d

# 查看遠端已刪除但本地還存在的分支
git remote prune origin --dry-run

# 實際清理
git remote prune origin

分支相關的實用指令

比較分支

# 查看兩個分支的差異
git diff main feature/user-login

# 查看分支的提交差異
git log main..feature/user-login

# 查看分支的檔案差異
git diff --name-only main feature/user-login

追蹤分支資訊

# 查看分支的追蹤關係
git branch -vv

# 設定目前分支的上游分支
git branch --set-upstream-to=origin/feature/user-login

# 查看分支的提交者和最後提交時間
git for-each-ref --format='%(refname:short) %(committerdate) %(authorname)' refs/heads/

處理分支衝突的預防

保持分支同步

# 每天開始工作前
git switch main
git pull origin main

# 切換到功能分支並同步
git switch feature/my-feature
git merge main

# 或者使用 rebase 保持線性歷史
git rebase main

小而頻繁的提交

# 好的做法:小步快跑
git add login-form.html
git commit -m "新增登入表單 HTML 結構"

git add login-form.css
git commit -m "完成登入表單樣式"

git add login-validation.js
git commit -m "實作登入欄位驗證"

分支的進階技巧

重新命名分支

# 重新命名目前分支
git branch -m new-branch-name

# 重新命名其他分支
git branch -m old-name new-name

# 如果分支已推送到遠端
git push origin :old-name new-name
git push origin -u new-name

複製分支

# 從現有分支建立新分支
git switch -c feature/user-profile-v2 feature/user-profile

# 從特定提交建立分支
git switch -c hotfix/urgent-fix a1b2c3d

查看分支關係

# 查看分支的圖形化歷史
git log --oneline --graph --all

# 查看哪些分支包含特定提交
git branch --contains a1b2c3d

# 查看分支的共同祖先
git merge-base main feature/user-login

我的分支管理心得

作為一個經驗豐富的工程師,我想分享一些實戰經驗:

1. 分支命名要見名知意

# 好的命名讓你半年後還知道這個分支在做什麼
git switch -c feature/implement-oauth-login
git switch -c bugfix/fix-responsive-navbar
git switch -c hotfix/patch-security-vulnerability

# 避免模糊的命名
git switch -c my-branch
git switch -c fix
git switch -c temp

2. 功能分支要保持短命

理想情況下,一個功能分支的生命週期不應該超過一週。如果超過了,考慮將功能拆分成更小的部分。

# 與其建立一個大型分支
git switch -c feature/complete-user-system

# 不如拆分成多個小分支
git switch -c feature/user-registration
git switch -c feature/user-login
git switch -c feature/user-profile
git switch -c feature/password-reset

3. 定期清理分支

# 每週檢查並清理已完成的分支
git branch --merged | grep -v "main"

# 刪除已合併的功能分支
git branch -d feature/completed-feature

# 查看很久沒有更新的分支
git for-each-ref --format='%(refname:short) %(committerdate)' refs/heads | sort -k2

分支策略的選擇建議

小型團隊(2-5人)推薦 GitHub Flow

# 簡單的兩分支模式
main              # 主分支,隨時可部署
feature/*         # 功能分支

操作流程:

git switch main
git pull origin main
git switch -c feature/new-feature
# 開發...
git push -u origin feature/new-feature
# 建立 Pull Request
# 合併後刪除分支

中型團隊(5-15人)推薦 GitLab Flow

main              # 開發主分支
production        # 生產環境分支
feature/*         # 功能分支

大型團隊(15人以上)推薦 Git Flow

main              # 生產環境分支
develop           # 開發環境分支
feature/*         # 功能分支
release/*         # 發布分支
hotfix/*          # 緊急修復分支

分支保護的重要性

在生產環境中,我們通常會設定分支保護規則:

在 GitHub 上設定保護規則

  1. 進入倉庫的 Settings
  2. 選擇 Branches
  3. 新增 Branch protection rule for main
  4. 啟用以下選項:
    • Require pull request reviews before merging
    • Require status checks to pass before merging
    • Restrict pushes that create files larger than 100MB

在本地模擬保護

# 設定 Git hooks 來防止直接推送到 main
# 這需要在 .git/hooks/pre-push 中加入腳本

常見的分支問題與解決方案

問題 1:忘記在哪個分支

# 檢查目前分支
git branch

# 或查看詳細狀態
git status

問題 2:在錯誤的分支上開發

# 如果還沒提交,可以暫存變更並切換分支
git stash
git switch correct-branch
git stash pop

# 如果已經提交,可以使用 cherry-pick
git switch correct-branch
git cherry-pick commit-hash

問題 3:分支名稱打錯

# 重新命名分支
git branch -m wrong-name correct-name

# 如果已經推送到遠端
git push origin :wrong-name correct-name
git push origin -u correct-name

分支的視覺化查看

# 簡潔的圖形化歷史
git log --oneline --graph

# 所有分支的圖形化歷史
git log --oneline --graph --all

# 更詳細的圖形化顯示
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --all

小結

分支管理是 Git 的精髓,掌握了分支,你就掌握了現代軟體開發的核心技能:

核心指令回顧:

  • git branch – 查看和管理分支
  • git switch -c – 建立並切換分支
  • git switch – 切換分支
  • git branch -d – 刪除分支
  • git merge – 合併分支

重要概念:

  1. 分支是輕量級的,建立和切換都很快
  2. HEAD 指標告訴你目前的位置
  3. 選擇適合團隊規模的分支策略
  4. 良好的命名規範讓協作更順暢

在下一篇文章中,我們將學習合併分支和處理衝突,這是團隊協作中必須掌握的重要技能。


記住,分支不是用來展示你的技術有多複雜,而是用來讓開發流程更安全、更有組織。從簡單的功能分支開始練習,慢慢建立你的分支管理習慣。

404NOTE
404NOTE
文章: 40

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *