如果說 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
命名最佳實踐
- 使用小寫字母和連字符
# 好的命名
feature/user-profile
bugfix/login-error
# 避免的命名
Feature/UserProfile
bugfix_login_error
- 包含簡短的描述
# 清楚明瞭
feature/shopping-cart
hotfix/payment-timeout
# 過於模糊
feature/stuff
fix/bug
- 包含票號或任務編號
# 如果使用任務管理系統
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 上設定保護規則
- 進入倉庫的 Settings
- 選擇 Branches
- 新增 Branch protection rule for
main
- 啟用以下選項:
- 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
– 合併分支
重要概念:
- 分支是輕量級的,建立和切換都很快
- HEAD 指標告訴你目前的位置
- 選擇適合團隊規模的分支策略
- 良好的命名規範讓協作更順暢
在下一篇文章中,我們將學習合併分支和處理衝突,這是團隊協作中必須掌握的重要技能。
記住,分支不是用來展示你的技術有多複雜,而是用來讓開發流程更安全、更有組織。從簡單的功能分支開始練習,慢慢建立你的分支管理習慣。