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 总结一个简化框架

下面这张图总结了代码仓库与分支策略的核心逻辑。你可以把它贴在墙上当参考。

代码仓库与分支策略选择框架 团队规模与发布节奏 小团队 / 持续交付 中型团队 / 固定版本 大型团队 / 高频集成 GitHub Flow Git Flow / GitLab Flow Trunk-Based PR 触发 CI 快速验证 + 自动部署 分支类型匹配流水线 feature/release/hotfix 各不同 频繁合并+短分支 每次提交跑全量测试 常见问题 (Q&A) • 分支生命周期太长 → CI 反馈慢,合并冲突多 → 采用短分支+每日合并 • CI 流水线不分级 → 所有分支跑同样测试 → 按分支类型配置不同 job • 保护规则设置不当 → 阻塞正常发布 → 按紧急程度分级审批 选择策略 → 规范分支 → 适配 CI = 稳定交付

这张图把选择分支策略的流程拆成了三步:先看团队规模和发布节奏,再选对应策略,最后把 CI 流水线按分支类型差异化配置。左下角的常见问题是我在实际复盘时总结的,你可以对照着检查自己团队有没有踩坑。

最终建议:没有银弹。Git Flow 不总是最佳,Trunk-Based 也不是万能。我现在的团队用 GitHub Flow + 极短 feature 分支,配合每两小时自动合并到预发环境,CI 稳定度达到 99.5%。但这套方案如果拿到做嵌入式固件的团队,可能就崩了。所以,选你团队能扛得住的策略。