3. 代码仓库与分支策略归纳总结
分支策略这东西,说白了就是团队在代码仓库上怎么协作的一套规矩。我这些年见过不少项目,明明功能写得很溜,但分支乱得像一团麻,合代码的时候天天冲突,CI 跑得一塌糊涂。其实选对分支策略,CI/CD 就稳了一半。
3.1 分支策略的核心要素
不管什么策略,都得回答几个问题:
- 主线在哪? 是 master/main,还是 develop?
- 什么时候开新分支? 改 bug、加功能、发版本,各有各的规矩。
- 合并回主线的条件是什么? 必须通过 CI、必须 code review?
- 发布怎么打标签? 直接从主线走,还是从发布分支走?
我建议先想清楚这四点,再套现成的策略,别生搬硬套。
3.2 主流分支策略对比
市面上常见的策略就那几套,我挑三个讲清楚。
| 策略 | 核心分支 | 适合场景 | CI 配合 |
|---|---|---|---|
| Git Flow | master + develop + feature + release + hotfix | 版本发布周期固定,有多个并行版本 | 每个分支类型触发不同 CI 流水线,发布流程长 |
| GitHub Flow | master + feature(短期) | 持续交付、快速迭代、Web 应用 | PR 自动跑 CI,合并即部署 |
| Trunk-Based | 主分支 + 极短生命周期分支 | 大团队、高频集成、需要快速反馈 | 每次提交即触发 CI,禁止长寿分支 |
我个人习惯是:如果团队小、产品迭代快,用 GitHub Flow 就够了。如果产品需要同时维护老版本和新版本,比如移动端 App,那 Git Flow 更合适。至于 Trunk-Based,适合那种“一次提交就要立刻上线”的玩法,但要求测试覆盖率和 CI 质量极高。
关键认知:分支策略不是越复杂越好。我见过有人把 Git Flow 的所有分支都用上,结果 feature 分支一周不合并,develop 已经落后 master 两个版本了。CI 跑得欢,但合代码时哭都没地方哭。
3.3 分支策略与 CI 的联动
动态交付 CI 跑的是代码,但代码在哪个分支上跑,差别很大。我一般这么配置:
- 主分支(master/main): 每次合并自动跑完整流水线 —— 单元测试、集成测试、安全扫描、部署到预发环境。如果失败,不允许任何合并操作。
- 特性分支(feature): 每次 push 只跑快速验证 —— 编译 + 单元测试。10 分钟内给结果,不影响开发效率。
- 发布分支(release): 跑回归测试 + 性能测试。这个环节慢,但必须稳定。
- 修复分支(hotfix): 优先跑 CI,甚至可以跳过测试直接部署到生产。但得加一个人工审批。
有一次我接手一个项目,特性分支的 CI 居然跑全量集成测试,一次要 45 分钟。开发者 push 后就去干别的,回来一看又挂了,一天改不了几个 bug。后来我把特性分支的 CI 改成只跑“受影响的模块测试”,配合增量扫描,时间压缩到 8 分钟。嗯,幸福感提升不少。
# 示例:GitHub Actions 中根据不同分支触发不同 job
on:
push:
branches:
- 'main' # 主分支触发完整流水线
- 'feature/**' # 特性分支触发快速验证
jobs:
quick-check:
if: startsWith(github.ref, 'refs/heads/feature/')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Fast Test
run: npm run test:unit -- --changedSince=main
full-pipeline:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Full Test
run: npm run test:all
- name: Security Scan
run: npm audit
小技巧:特性分支上跑 CI 时,可以用 git diff 算出改动范围,只跑相关的测试。我在项目中用这个方案后,CI 排队时间少了 70%。
3.4 分支命名规范 —— 容易被忽视的细节
分支名字乱,CI 流水线条件判断就不好写。我建议强制规范:
| 分支类型 | 命名示例 | CI 匹配规则 |
|---|---|---|
| 特性分支 | feature/JIRA-123-add-login | feature/* |
| 发布分支 | release/1.2.0 | release/* |
| 修复分支 | hotfix/1.1.1-fix-crash | hotfix/* |
你想想看,如果每个人起名都随性,比如 fix-bug、my-work,那你 CI 脚本里写正则匹配得多痛苦?而且后续清理旧分支时,根本分不清哪些能删。
3.5 我的避坑指南
- 不要开长寿命分支。 我见过一个项目,feature 分支开了三个月,合并时冲突上千行。CI 跑了三天才通过,最后发现代码逻辑已经和主线完全不兼容。你想想,这代价多大?
- 不要直接在 master 上提交。 我以前有个同事,图省事,改了一个配置直接推 master,结果 CI 没触发(他忘了 push tag),生产挂了半小时。从那以后我强制要求所有改动必须走 PR + CI。
- 保护分支,但别过度。 有些团队把 master 设为只读,还必须两个 reviewer 同意。结果小 bug 修一天都合不进去。我建议区分对待:master 要求至少一个人 review,hotfix 可以允许 owner 直接合并。
警告:分支策略选错,CI 配置再漂亮也白搭。曾经有个团队用了 Trunk-Based 策略,但 CI 每次都要跑 30 分钟,开发者一天只能提交两次。完全背离了“频繁集成”的初衷。所以选策略前,一定要摸清团队的节奏和 CI 的承载能力。
3.6 总结一个简化框架
下面这张图总结了代码仓库与分支策略的核心逻辑。你可以把它贴在墙上当参考。
这张图把选择分支策略的流程拆成了三步:先看团队规模和发布节奏,再选对应策略,最后把 CI 流水线按分支类型差异化配置。左下角的常见问题是我在实际复盘时总结的,你可以对照着检查自己团队有没有踩坑。
最终建议:没有银弹。Git Flow 不总是最佳,Trunk-Based 也不是万能。我现在的团队用 GitHub Flow + 极短 feature 分支,配合每两小时自动合并到预发环境,CI 稳定度达到 99.5%。但这套方案如果拿到做嵌入式固件的团队,可能就崩了。所以,选你团队能扛得住的策略。