上周有个前同事问我,他们团队9个人,用Git Flow半年,每次发版前三天都在修合并冲突,问我是不是该换Trunk-Based。
我没直接回答,因为2022年我在一家200人的SaaS公司做过类似实验,结果挺反直觉的。
当时我们选了12个业务团队,每组6到11人,代码库都是Java + Spring Boot,CI用GitLab 14.5,平均流水线8分30秒。
A组继续Git Flow,release分支生命周期14天;B组切到GitHub Flow,main分支保护,feature分支不超过3天;C组强制Trunk-Based,每天至少合并2次到main,配合LaunchDarkly做功能开关。
跑了6个月,收集了4382次合并请求的数据,你猜怎么着?Trunk-Based的合并冲突率确实最低,每100次合并只有2.3次冲突,Git Flow是11.7次。
但C组的回滚率是A组的3.2倍,因为功能开关没配好,有17次把未完成功能推到了生产。
所以问题不是哪个模型更好,而是你的团队能不能承受高频集成的代价。
如果你决定试Trunk-Based,别一上来就全员切换,我建议先用一个非核心服务跑两周。
具体步骤:第一,把main分支保护打开,要求至少1个approve和流水线通过才能合并。
第二,配置git config --global pull.rebase true,避免无意义的merge commit。
第三,提交信息强制用Conventional Commits,比如feat(auth): add OAuth2 PKCE,这样自动生成changelog时不会头疼。
第四,功能开关必须用,推荐@FeatureToggle注解加配置中心,别用if-else硬编码。
第五,CI里加interruptible: true,让新推送取消旧流水线,我们当时省了34%的runner时间。
这些参数看着琐碎,但少一个都会出问题,尤其是功能开关,我们那17次生产事故全是因为有人偷懒直接改了代码。
再说个反例。我见过一个5人小团队,盲目学Netflix的Trunk-Based,没有自动化测试,没有功能开关,结果main分支挂了6次,每次修2小时。
后来他们退回Git Flow,但做了个改动:把release分支从14天缩到3天,合并频率提高到每天1次,冲突率反而降了40%。
所以我的独立观点是:版本控制的核心不是分支模型,而是“集成频率”和“认知负载”的平衡。
Git Flow不是原罪,Trunk-Based也不是银弹。
你要算的是:每次合并冲突的平均解决时间 × 冲突频率 + 功能开关的维护成本,和发布延迟的业务损失哪个更大。
如果你们团队连每天开一次站会都嫌烦,那Trunk-Based就是灾难。
最后给个可查证的细节。Git 2.34之后,git switch和git restore已经足够稳定,建议替换掉git checkout,减少误操作。
git rebase --autosquash配合fixup!提交,能把review后的修改自动合并到原提交,我们团队用这个把rebase时间从平均7分钟降到2分钟。
还有,别迷信squash merge,它会让git bisect变得困难,除非你的每次提交都是原子性的。
我们后来改用rebase merge,保留线性历史,同时每个提交都能编译通过。
这些细节,比争论Git Flow还是Trunk-Based有用得多,毕竟工具是死的,人是活的。
你团队现在用的什么模型?踩过什么坑?可以评论区聊聊。