分支策略決定了團隊如何並行開發、如何整合、以及如何發布。沒有「最好」的策略,只有「最適合當前團隊與發布節奏」的策略。本章比較四種主流模型,並提供選型決策表。


一、為什麼分支策略很重要#

分支策略本質上是在回答三個問題:

  • 工作如何隔離:新功能、修復、實驗各自在哪裡進行?
  • 變更如何整合:什麼時候、用什麼方式把變更合回主線?
  • 版本如何發布:哪條分支代表「正式上線的程式碼」?

分支策略的核心矛盾是:分支隔離了風險,卻也延遲了整合。分支活得越久,與主線的偏離越大,最終合併時的衝突與風險也越高。


二、Git Flow#

Git Flow 是最早被廣泛採用的結構化模型,圍繞多條長命分支建立嚴謹的發布流程。

分支角色
main永遠對應已上線的正式版本,每次合併都打 tag
develop整合中的下一個版本
feature/*develop 切出,完成後合回 develop
release/*準備發布,只允許修 bug 與調整版本號
hotfix/*main 切出緊急修復,合回 maindevelop
gitGraph
    commit id: "init"
    branch develop
    checkout develop
    commit
    branch feature/login
    checkout feature/login
    commit
    commit
    checkout develop
    merge feature/login
    branch release/1.0
    checkout release/1.0
    commit id: "bump 1.0"
    checkout main
    merge release/1.0 tag: "v1.0"
    checkout develop
    merge release/1.0

Git Flow 適合有明確版本概念、需要同時維護多個版本的產品(如桌面軟體、需長期支援的 SDK)。但對追求每日多次發布的 Web 服務而言,它的長命分支會拖慢整合節奏。


三、GitHub Flow#

GitHub Flow 極度簡化:只有一條長命分支 main,其餘都是短命的 feature 分支。

gitGraph
    commit
    branch feature/search
    checkout feature/search
    commit
    commit
    checkout main
    merge feature/search tag: "deploy"
    branch feature/cart
    checkout feature/cart
    commit
    checkout main
    merge feature/cart tag: "deploy"

工作流程:

  1. main 切出描述性命名的分支(如 feature/search)。
  2. 持續提交,推送到遠端,開啟 Pull Request。
  3. 通過審查與 CI 後合併回 main
  4. main 隨時可部署,合併即發布。

GitHub Flow 假設 main 永遠可部署,因此高度依賴自動化測試與 CI。適合持續部署的 Web 服務與單一正式版本的產品。


四、GitLab Flow#

GitLab Flow 在 GitHub Flow 之上補回「環境」與「版本」的概念,用環境分支或 release 分支銜接部署流程。

環境分支變體(適合持續部署到多環境):

flowchart LR
    F[feature/*] -->|MR| M[main]
    M -->|自動/手動推進| S[staging]
    S -->|驗證後推進| P[production]
  • main 合併後自動部署到測試環境。
  • 通過驗證後,把 main 合併進 staging、再合併進 production程式碼只能單向往下游環境流動

release 分支變體(適合需要對外發布版本號的產品):

  • main 切出 release/2.3,正式版本從這裡產生。
  • 修復先進 main,再 cherry-pick 回需要的 release 分支(upstream first 原則)。

GitLab Flow 的核心原則是 upstream first:任何修復都先進入主線,再往下游分支傳播,避免下游修復遺漏回主線造成「修了又壞」。


五、Trunk-Based Development#

主幹開發(TBD)把整合做到極致:所有人都頻繁地(每天至少一次)把小變更直接整合進主幹 main,分支生命週期以小時或一兩天計。

gitGraph
    commit
    commit
    branch short-lived
    checkout short-lived
    commit
    checkout main
    merge short-lived
    commit
    branch short-lived-2
    checkout short-lived-2
    commit
    checkout main
    merge short-lived-2
    commit
  • 未完成的功能用 Feature Flags 隱藏,而非用長命分支隔離(見 ../03-ci-cd-and-pipelines/)。
  • 發布時從主幹切出短命的 release 分支,或直接從主幹某個 commit 發布。

TBD 是持續整合的「原教旨」實踐,也是高效能 DevOps 團隊的常見選擇。它要求成熟的自動化測試與 Feature Flag 基礎設施,否則頻繁直推主幹會頻繁破壞建置。


六、分支拆分維度#

跳脫具體模型,分支策略其實是沿三個維度切分工作:

維度做法風險
Branch by Feature每個功能一條分支功能越大分支活越久,整合衝突越大
Branch by Release每個發布版本一條分支修復需在多版本間移植(backport)
Branch by Team每個團隊一條長命分支團隊間整合被嚴重延遲,最易產生大爆炸式合併

Branch by Team 看似讓團隊互不干擾,實則把整合風險累積到最後一刻。團隊規模越大越應避免,改以模組化/服務化在程式碼層面解耦。


七、與持續整合的張力#

分支策略與 CI 存在本質張力:

flowchart LR
    A[長命分支] -->|延遲整合| B[合併時衝突大]
    B --> C[整合風險高]
    D[短命分支 / 主幹開發] -->|頻繁整合| E[小步衝突]
    E --> F[整合風險低]
  • 長命分支 提供強隔離,但每多活一天就離主線更遠,違背 CI「頻繁整合」的初衷。
  • 短命分支 / 主幹開發 持續整合,衝突小而頻繁、容易處理,但要求 main 隨時綠燈。

「持續整合」的字面意思就是持續地把變更整合進共用主線。任何讓分支長期不合回主線的策略,嚴格來說都在削弱 CI。


八、選型決策表#

因素Git FlowGitHub FlowGitLab FlowTrunk-Based
團隊規模中~大小~中任意(含大型)
發布頻率低(週/月)高(每日)中~高極高(持續部署)
多版本維護中(release 變體)
多環境部署強(環境變體)
CI/自動化要求極高
Feature Flag 依賴
flowchart TD
    A[選擇分支策略] --> B{需要同時維護<br/>多個發布版本?}
    B -->|是| C[Git Flow 或<br/>GitLab Flow release 變體]
    B -->|否| D{有成熟的 CI 與<br/>Feature Flag?}
    D -->|是| E[Trunk-Based Development]
    D -->|否| F{需要多環境<br/>逐級部署?}
    F -->|是| G[GitLab Flow 環境變體]
    F -->|否| H[GitHub Flow]

不確定時,從 GitHub Flow 起步:它最簡單,且能隨團隊成熟逐步演進到 GitLab Flow 或 Trunk-Based。過早採用 Git Flow 的繁複流程,往往是團隊感受到摩擦的常見來源。


九、命名慣例#

無論選哪種策略,一致的分支命名能讓追蹤與自動化更容易:

feature/<issue-id>-short-description   # 新功能
bugfix/<issue-id>-short-description    # 一般修復
hotfix/<issue-id>-short-description    # 緊急上線修復
release/<version>                      # 發布準備

在分支名中嵌入 issue 編號,可讓 commit、分支、議題追蹤系統自動關聯,分支本身就成為一份可追溯的工作紀錄。延伸用法見 ../04-merge-request-workflow/