为什么需要分支策略
一个人写代码时,直接在 main 上提交就够了。但团队多人并行开发,问题立刻出现:谁都往同一条线上推,昨天刚发的版本被今天的半成品带崩,合并时还要面对一大堆互相覆盖的冲突。
分支策略要解决的,其实是三个问题:大家在哪里并行、怎么合回去、出了问题怎么快速退回来。策略不是 Git 的高级技巧,而是团队约定——定得清楚,每个人都知道该从哪里切分支、合到哪里去。
分支用得乱,不是 Git 的错,是团队没有约定好怎么用它。
- 主线永远是一条可随时发布的稳定线。
- 短分支分支活得越短,合并冲突越少。
- 门禁合入主干前必须过评审与自动检查。
- 可回滚出问题能分钟级退回上一个版本。
- 匹配策略要匹配团队规模与发布节奏,不追新潮。
GitHub Flow:一条主线加短分支
GitHub Flow 是最容易上手的一套:main 永远可发布,每个改动都开一个短命分支,做完就合回去。规则简单到能贴在墙上。
# 一次典型的 GitHub Flow 循环(命令为示意)
从最新 main 切一个新分支:
git switch -c feature/购物车优惠券
在这个分支上小步提交、随时推送备份:
git commit -m "加上满减规则"
推送后发起合并请求,请人评审、跑 CI:
git push -u origin feature/购物车优惠券
评审与检查都通过后合回 main,删掉这条分支:
git merge feature/购物车优惠券
git branch -d feature/购物车优惠券
它的关键不是流程本身,而是分支活不久:一个分支几天内就合回去,改动面小,冲突少,回滚也容易。适合持续发布的产品团队。
Trunk Based:小步直奔主干
比 GitHub Flow 更激进的是 Trunk Based:开发者几乎直接往主干提交,只是把一个完整的大改动拆成很多小步,每步都能独立合并上线。没做完的部分用开关藏起来,而不是用长分支藏起来。
| 做法 | 短分支(GitHub Flow) | 主干直推(Trunk Based) |
|---|---|---|
| 并行方式 | 一人一条短分支 | 大家在主干上小步前进 |
| 未完成功能 | 留在分支里 | 用特性开关先藏起来 |
| 前提 | 评审与 CI 成熟 | 测试与自动化极成熟 |
| 适合 | 多数中小团队 | 高成熟度、超高频发布团队 |
Trunk Based 换来的是几乎没有「合并地狱」的代价,但它对自动化测试和特性开关的要求很高,不是想上就能上。
功能分支与发布分支怎么取舍
还有一类做法是同时维护长期的功能分支和发布分支:功能在 feature 分支上开发,准备上线时切出 release 分支做最后修整,再合回主干并打版本标签。
- 适合需要按月、按版本发版,且要同时维护多个旧版本的团队(比如客户端、有线下交付的软件)。
- 代价是分支数量多、生命周期长,合并冲突和「为什么这个版本没带上那个修复」会变多。
取舍原则很朴素:发版节奏越频繁,越应该用短分支或主干直推;越需要长期维护多个并行版本,才越需要发布分支。
合并前的评审与 CI 门禁
无论选哪种策略,合入主干这一步都应该有一道自动门禁,而不是靠人盯着。门禁做对了,主干天然就是干净的。
# 合并请求触发一条自动流水线(示意)
跑全套单元测试 # 有一条红就拦下
构建并打包 # 保证能编译出可用产物
静态与漏洞扫描 # 可疑写法和依赖漏洞直接标红
必要的人代码评审 # 至少一位同事点同意
# 全部绿灯,才允许合回 main;
# main 因此永远处在「可发布」的状态。
门禁把「别合坏代码」从个人自觉,变成了系统不让它合。这也是短分支敢频繁合并的底气。
处理冲突与回滚
冲突不可避免,关键是怎么让它少、好处理。第一原则就是分支要短、合并要勤:分支拖得越久,和主干差得越远,冲突越像一场重新写。
| 情形 | 推荐做法 |
|---|---|
| 多人改同一文件 | 勤同步主干,小步提交,冲突早暴露 |
| 合错代码到主干 | 用一次反向提交整体退回,再修 |
| 线上版本出问题 | 优先回滚上一个版本,再排查根因 |
| 大改动难拆分 | 用特性开关分阶段上线,别用长分支 |
好的分支策略让回滚变成一次操作,而不是一场抢救。
选策略没有标准答案
最后要说清楚:没有哪种分支策略是「最先进」的。GitHub Flow、Trunk Based、发布分支,各自服务于不同的团队状态。
- 测试和 CI 还不成熟时,先从 GitHub Flow 的短分支做起,把门禁跑顺。
- 发布已经高频、自动化很扎实,再考虑往 Trunk Based 演进。
- 需要长期并行维护多个版本时,保留发布分支是合理选择,不必硬凑新潮。
真正重要的不是策略名字,而是团队是不是都清楚同一条约定:从哪里切、往哪里合、怎么回退。约定清晰,Git 才是协作工具,而不是互相踩踏的雷区。