Git 分支模型:Flow 与 Trunk-Based

Git 分支模型决定了团队的协作方式与交付节奏。选错模型,轻则合并冲突频发、发布提心吊胆,重则主干长期不可发布。本文对比最主流的两种分支策略——Git Flow 与 Trunk-Based Development,并结合分支保护、CI 流水线与团队成熟度,给出中小团队可直接落地的协作规范。

一、为什么分支模型值得认真选

分支模型不是”个人习惯”,而是团队协作的契约。它约定了:新功能在哪条分支开发、什么时候能合回主干、发布从哪条分支打标签、线上故障从哪里出补丁。契约越清晰,协作成本越低;契约越模糊,每个人都在用自己的理解改同一份代码,冲突与回滚就成了日常。

一个常见误区是”分支越多越安全”。事实上,长期存在的分支会不断偏离主干,合并窗口越晚、冲突越大。好的分支模型追求的是”短生命周期”与”高频集成”,而非分支数量。

二、Git Flow:经典的多分支模型

2.1 核心分支与职责

Git Flow 由 Vincent Driessen 在 2010 年提出,定义了五类分支:main/master 保存正式发布历史,develop 是日常集成分支,feature/* 从 develop 拉出做功能开发,release/* 用于发布前的打磨与修 bug,hotfix/* 从 main 拉出做线上紧急修复。它的生命周期命令如下:

# 初始化(git flow 扩展)
git flow init

# 新功能
git flow feature start user-auth
# ... 开发 ...
git flow feature finish user-auth   # 合回 develop

# 发布分支
git flow release start 1.4.0
git flow release finish 1.4.0       # 合回 main 与 develop,打 tag

# 线上热修
git flow hotfix start 1.4.1
git flow hotfix finish 1.4.1

2.2 适用场景与痛点

Git Flow 适合版本化发布、发布节奏固定的项目,比如按季度交付的客户端软件、有严格版本号的 SDK。但对于每天多次上线的 Web 服务,它显得笨重:release 分支长期存在、hotfix 要同时合两条线、develop 与 main 的”双主干”容易让人困惑。这也是为什么很多团队后来迁移到 Trunk-Based。

三、Trunk-Based Development:短生命周期分支

Trunk-Based Development(主干开发)的核心理念只有一个:所有人尽量直接往主干(trunk/main)提交,功能分支的存活时间以小时计,最长不超过两天。它不靠”多分支隔离”保证稳定,而靠”高频集成 + 强 CI 门禁”保证稳定。

3.1 两条落地路径

小团队可以直接往 main 推(配合特性开关);稍大的团队用”短分支 + Pull Request”做轻量评审,但要求 PR 当天合入:

# 从主干拉一个短命分支
git checkout -b feat/search main
# ... 小步提交,频繁 rebase 主干 ...
git fetch origin && git rebase origin/main
git push -u origin feat/search
# 开 PR,CI 全绿后当天 squash 合入,立即删分支
git branch -d feat/search

3.2 为什么大厂偏爱它

Google、Meta 等超大规模团队几乎都采用 Trunk-Based,因为分支越短,合并冲突的可怕程度越低;配合特性开关(Feature Flag),未做完的功能也能安全地合进主干而不对用户可见。代价是工程基建要求高:必须有快速、可靠的 CI 与完善的测试套件,否则主干一旦挂掉全员阻塞。关于 rebase 与 cherry-pick 的高频踩坑,可参考 Git rebase 与 cherry-pick 实战踩坑

四、两种模型核心差异对照

维度Git FlowTrunk-Based
常驻分支数多(main/develop/release/hotfix)少(基本只有 main)
功能分支寿命天到周小时到两天
集成频率低,按发布窗口高,每天多次
回滚难度中,需切 release/hotfix低,主干可直接 revert
适合团队版本化、发布慢持续交付、Web 服务

五、分支保护 + CI:模型落地的保障

5.1 保护规则怎么设

无论选哪种模型,都应给主干(main)和集成分支(develop)开启分支保护:禁止直接 push、要求 PR 评审、要求 CI 检查通过、要求分支最新(up to date)。GitHub 的保护规则大致如下:

{
  "required_status_checks": { "strict": true, "contexts": ["ci/build", "ci/test"] },
  "enforce_admins": true,
  "required_pull_request_reviews": { "required_approving_review_count": 1 },
  "restrictions": null
}

5.2 与 CI 流水线配合

保护规则只是开关,真正把关的是 CI。合并前必须跑构建、跑测试、跑静态检查。Trunk-Based 尤其依赖”快 CI”——开发者提交后几分钟内应拿到结果。CI 的具体写法可参考 GitHub Actions 实战:从零搭建 CI/CD 流水线GitLab CI/CD 实战:缓存、制品与多环境部署

# .github/workflows/ci.yml 节选
name: ci
on: [pull_request]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build
      - run: npm test

六、选型决策:你的团队该用哪种

团队特征推荐模型理由
每天多次上线、有完善测试Trunk-Based高频集成,冲突最小
按版本发布、节奏固定Git Flowrelease/hotfix 语义清晰
1-5 人小团队起步Trunk-Based(轻量)流程负担最低
多版本长期并行维护Git Flow 变体需独立维护旧版本线

七、可直接落地的协作规范清单

条目规范要求
分支命名feat/*、fix/*、chore/*,语义清晰可追溯
分支寿命Trunk-Based 下不超过 2 天,超时即重建
提交粒度一个提交一件事,消息写”为什么”而非”做了什么”
合并方式优先 squash,保持主干线性历史
评审门槛主干保护 + 至少 1 人审批 + CI 全绿
清理机制合入即删远程分支,定时清理 stale

规范的本质是降低协作的认知负担。关于”何时该为流程付出工程成本”,可延伸阅读 技术债不是原罪:在速度与质量间做工程决策;而衡量流程是否真的提效,可以看 研发效能度量:用 DORA 指标驱动团队提速 中的部署频率与变更前置时间。

八、常见反模式与排障

反模式一:长命 feature 分支。一个月不合并的功能分支,合回时必然是”冲突地狱”。解法:拆小、用特性开关、每天 rebase 主干。

反模式二:跳过保护规则。有人图快直接 push 主干,一次失误就是全员事故。enforce_admins 必须开启,连管理员也禁绕。

反模式三:CI 太慢被绕过。CI 跑 30 分钟,开发者就会”先合再修”。保持 CI 在 10 分钟内,并把测试分层次并行。

定期清理已合并的远程分支,可用一段简单脚本:

# 删除已合入 main 的本地分支
git branch --merged main | grep -v 'main' | xargs -r git branch -d
# 删除 30 天无更新的远程分支(需确认)
git fetch -p

九、小结

Git 分支模型没有绝对优劣,只有”是否匹配你的交付节奏”。版本化、慢发布选 Git Flow;持续交付、快上线选 Trunk-Based。无论哪种,都要用分支保护和强 CI 兜底,并把规范写成团队共识。分支是手段,稳定高效地把代码送到用户手里,才是目的。关于技术选型的通用方法论,可参考 技术选型决策矩阵:在权衡中做对选择

上一篇 前端路由原理与实战:Hash 与 History 模式选型
下一篇 Spring Boot GraalVM 原生镜像编译实战