2. Git 分支策略:主分支、开发分支、发布分支、热修复分支的协作模型
分支策略这东西,说白了就是团队怎么在 Git 里「并道行驶」。我见过太多项目,一开始没规划好,最后合并时冲突堆成山,发布窗口一拖再拖。今天聊的这套模型,是我在多个全量包项目中反复打磨过的,核心就四个分支类型。
2.1 四个核心分支,各司其职
先看一张整体结构图,后面我们再逐个拆解。
2.2 main 分支:永远可部署
main 分支只有一个铁律:任何时候 checkout 出来,代码都是可部署的。我在项目中遇到过有人直接往 main 上 push 未测试的代码,结果线上回滚了三次。从那以后,我强制 main 分支只能通过 Pull Request 合并,而且必须经过 CI 全量流水线。
核心原则:main 分支的每一次提交,都应该对应一个可追溯的版本号。全量包制作时,直接从 main 打 tag 拉取代码,不要从其他分支拉。
2.3 develop 分支:日常集散地
develop 是团队日常工作的主干。所有功能分支、个人分支都从这里拉出,开发完再合并回来。说白了,这就是大家的「碰头点」。
我个人习惯在 develop 上开启 CI 的「轻量级检查」——只跑单元测试和代码规范,不跑全量集成测试。为什么?因为 develop 变化太快,全量跑一遍要 40 分钟,太浪费。全量测试留给 release 分支去做。
小技巧:develop 分支建议设置「线性历史」策略,禁止 merge commit,只允许 squash merge 或 rebase。这样历史干净,回查问题时一目了然。
2.4 release 分支:发布前的质检站
当 develop 的功能攒够一个发布周期,就从 develop 拉出 release 分支。命名规则我推荐 release/v1.2.3 这种格式,版本号一目了然。
release 分支上只做三件事:
- Bug 修复——只修不增,严禁加新功能
- 版本号更新——全量包的版本文件、CHANGELOG 都在这里定稿
- 全量回归测试——跑完整的集成测试、性能测试、安全扫描
我记得有一次,团队在 release 分支上发现一个内存泄漏,修完后忘记合并回 develop。结果下一个版本又出现了同样的问题。嗯,这里要注意:release 分支的修复,必须双向合并——合并到 main 打 tag,同时合并回 develop。
警告:release 分支的生命周期应该很短,一般不超过 3 天。拖太久,develop 上的新代码和 release 的差异越来越大,合并时冲突会让人崩溃。
2.5 hotfix 分支:线上救火队
线上出了紧急 Bug,等不了下一个发布周期。这时候从 main 分支(注意,不是 develop)拉出 hotfix/2.3.1 分支。
为什么从 main 拉?因为 main 上的代码是当前线上运行的版本,修复基线最准确。如果从 develop 拉,可能混入了还没上线的功能,修复完反而引入新问题。
hotfix 的流程我总结为三步:
- 从 main 拉出 hotfix 分支,修复代码
- 合并回 main,打上补丁版本 tag(如 v2.3.1)
- 合并回 develop,确保下一个版本也包含这个修复
避坑指南:我曾经在 hotfix 合并时只合并了 main,忘了合并 develop。结果两周后发新版本,那个 Bug 又出现了。后来我写了个 Git 钩子,每次 hotfix 合并到 main 后自动创建合并到 develop 的 PR,才彻底解决。
2.6 feature 与 personal 分支:开发者的工作台
这两个分支是开发者的私人空间。feature 分支对应一个完整功能,personal 分支对应个人日常开发。我建议团队统一前缀:feature/order-system、personal/zhangsan/daily。
它们都从 develop 拉出,开发完成后合并回 develop。这里有个容易踩的坑:feature 分支不要跨度过大。一个 feature 分支如果开发超过 5 天,建议拆分成子任务,或者每天 rebase 一次 develop,否则合并时冲突量会指数级增长。
| 分支类型 | 拉出源 | 合并目标 | 生命周期 | CI 级别 |
|---|---|---|---|---|
| main | — | — | 永久 | 全量流水线 |
| develop | — | — | 永久 | 轻量检查 |
| release/* | develop | main + develop | ≤ 3 天 | 全量回归 |
| hotfix/* | main | main + develop | ≤ 1 天 | 全量 + 紧急 |
| feature/* | develop | develop | ≤ 5 天 | 功能级 |
| personal/* | develop | develop | ≤ 1 天 | 无/手动 |
2.7 全量包制作中的分支选择
最后聊一个实战问题:做全量包时,到底从哪个分支拉代码?
我的答案是:永远从 main 分支的 tag 拉。不要从 develop 拉,不要从 release 拉。因为 main 上的每个 tag 都对应一个经过全量测试、已经上线的版本,可追溯、可回滚。
如果非要做一个「预发布全量包」用于灰度测试,可以从 release 分支拉,但必须在包名或元数据里标注 -rc(Release Candidate),让所有人知道这不是正式版本。
个人经验:我习惯在全量包制作脚本里加一个检查步骤——自动验证当前代码是否来自 main 分支的 tag。如果不是,直接报错退出。这个检查帮我拦截过至少 5 次「拿错分支打全量包」的失误。