版本控制与分支策略:不是选美,是选命
说实话,分支策略这东西,圈子里吵了十几年。有人把 Git Flow 奉为圣经,也有人一听到「长期分支」就皱眉。我的态度很简单:没有银弹,但一定有最适合你团队的套路。我自己在不同项目里换过三次策略,才慢慢摸清门道。
这章咱们就聊聊两个主流流派——Git Flow 和 Trunk-Based Development。我不打算念说明书,而是从实战视角告诉你:它们各自的「爽点」在哪儿,踩坑点又在哪儿。你想想看,选错了分支策略,CI 再漂亮也是白搭。
核心结论:分支策略决定了你的 CI 流程是「丝滑」还是「便秘」。选错了,每次合代码都像过鬼门关。
Git Flow:经典但易胖
我记得2016年刚接手一个微服务项目时,团队直接照搬了 Git Flow。示意图上看着漂亮——develop、release、hotfix 各司其职。但实际跑起来,分支数量像吹气球一样膨胀。每次上线前,光解决冲突就要花半天。
Git Flow 的核心套路就这几条:
- develop 是日常开发集散地。所有 feature 分支从这里拉,再合回来。
- release 分支用于打版前收尾。只修 bug,不加新功能。
- hotfix 分支从 master 拉。修完同时合进 master 和 develop,避免漏修。
- master 永远可部署。每次合并都打 tag。
嗯,听着挺完美对吧?但我踩过一次大坑:有一次团队同时维护三个版本,release 和 hotfix 交叉,最后 develop 和 master 的差异越来越大,合并时直接炸了。
我的建议:如果团队不到10人,或者发版节奏超过两周一次,Git Flow 带来的管理成本可能比收益大。不如考虑简化版。
Trunk-Based Development:短跑选手的武器
后来我跳槽到一家做 SaaS 的公司,要求每天发版好几次。Git Flow 明显吃不消了。我尝试引入 Trunk-Based Development。说白了就是一个主干(main),所有开发人员直接或通过短命分支提交代码,每天至少合入一次主干。
为什么会有人觉得这太激进?因为「主干必须一直保持绿色」意味着:你的 CI 必须快、准、稳。有一次我们没加好门禁,有人合了一行有问题的代码,阻塞了全组半小时。后来我们加了 pre-merge 检查和自动回滚,才稳住。
这里的关键点是:
- 分支存活时间不超过一天。超过一天的代码大概率会跟主干脱节。
- CI 跑得越快越好。我建议控制在5分钟内。超过10分钟,开发人员就会用「我先合上再说」的心态绕过门禁。
- 特性开关(Feature Toggle)是必需品。没完成的代码通过开关隐藏,而不是藏在分支里。
曾经我踩过的坑:没有特性开关就强推 Trunk-Based,结果未完成的功能被发布到了生产环境。还好是内部工具,不然就成大事故了。特性开关比你想的重要得多。
两条路,怎么选?
我们直接看对比表,不啰嗦:
| 维度 | Git Flow | Trunk-Based |
|---|---|---|
| 发版频率 | 周/月级 | 日级甚至小时级 |
| 分支复杂度 | 高(5种以上分支) | 低(1~2种) |
| 冲突风险 | 中(集中在合并时) | 低(分散到每次提交) |
| CI 门槛 | 低(可容忍较长流水线) | 高(需要极快速+高频CI) |
| 适合场景 | 传统企业、固定版本发布 | 微服务、SaaS、持续交付 |
我个人现在的习惯是:如果团队处于交付初期、还在搞 MVP,我会直接用 Trunk-Based。等产品稳定、需要同时维护多个版本时,再引入 Git Flow 的简化版——去掉 release 分支,只用 develop + master + hotfix。
实践要点:别让分支策略拖累 CI
不管你选哪条路,有几个坑你得避开。这些是我用真金白银换来的教训:
第一个建议:CI 流水线一定要在分支合并前运行。我之前试过「先合再跑 CI」,结果合进去一锅坏代码,回滚时所有人都在扒历史。
第二个建议:用 Git Hooks 或者 CI 规则拦住「不守规矩」的提交。比如禁止直接往 master 或 develop push,只允许通过 PR/MR 合入。
第三个建议:每次合并后,自动触发一次完整流水线。你可能会觉得浪费资源,但跟我遇到过「合并后测试通过了,部署时炸了」的情况相比,这点代价不算什么。
别忘了 git blame 的副作用:Trunk-Based 加上频繁 rebase 会导致 git blame 信息丢失。我们当时的解决方案是:只在 PR 合并时使用 squash merge,Commit 历史清晰又干净。到底用 merge 还是 rebase,我建议团队内统一规则,不然后面追查问题会吐血。
一句话总结
分支策略不是选好看的,是选能让你睡好觉的。Git Flow 给你确定性但牺牲速度,Trunk-Based 给你速度但需要更强的纪律和 CI 能力。别纠结对错,跟你的团队实际跑一遍就知道了。