1、更极致的理念
前面介绍的三种模型,都允许特性分支存在一定时间。但有一派人认为:分支存在的时间越长,合并冲突的风险越大,集成反馈越慢。
这就是 Trunk-Based Development(TBD,主干开发) 的核心主张:所有开发者直接在一个主干分支(trunk,即 main)上提交,或使用极短命的分支(不超过一天)。
TBD 不是什么新概念,Google、Facebook 等大型科技公司都采用这种模式。Google 有数万名工程师在同一个代码仓库上工作,用的就是主干开发。
2、核心原则
小步提交,频繁集成
TBD 要求开发者将工作拆分为足够小的改动,每天至少向主干合并一次。如果改动太大,就用 Feature Flag(特性开关) 来控制未完成功能的可见性。
main: ●─●─●─●─●─●─●─●─●─●─●─●─● (所有人直接提交或短分支合并)
│ │ │ │
└──┘ └──┘ (短分支,几小时到一天内合并)
短命分支
如果确实需要分支,它的生命周期应该非常短——通常不超过一天:
# 从 main 拉出
git checkout -b small-change main
# 做一些改动,几小时内提交
git add .
git commit -m "Small incremental change"
# 同步 main 的最新代码
git pull --rebase origin main
# 尽快合并回 main
git checkout main
git merge small-change
git push origin main
关键区别:传统模型中,一个 feature 分支可能存活数天甚至数周。TBD 中,分支应该在当天结束前就合并回主干。
3、Feature Flag(特性开关)
如果功能还没做完,不能直接暴露给用户怎么办?答案是 Feature Flag:
// 通过配置控制新功能是否可见
if (featureFlags.newDashboard) {
renderNewDashboard()
} else {
renderOldDashboard()
}
Feature Flag 让你可以:
- 将未完成的功能代码合并到主干,但不影响用户
- 灰度发布:先对 1% 用户开放,逐步放量
- 快速回滚:出问题时关闭开关即可,不需要回滚代码
- A/B 测试:同时运行新旧两套逻辑,对比效果
常用的 Feature Flag 管理方式:
- 配置文件(适合简单场景)
- 数据库或 Redis(适合动态控制)
- 专门的 Feature Flag 服务(如 LaunchDarkly、Unleash)
4、保证主干质量
如果所有人都往主干提交,怎么保证主干不坏?
自动化测试是底线
每次提交都必须通过完整的自动化测试。没有测试的 TBD 就是灾难。
# CI 配置示例
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm install
- run: npm run lint
- run: npm run test -- --coverage
- run: npm run build
提交前验证
合并到主干前,通常需要:
- 本地运行全套测试,确保不引入回归
- 代码审查:即使是小改动,也应该有人审查
- CI 检查:自动化流水线必须全绿
紧急修复流程
如果主干坏了怎么办?
- 立即停止新合并,优先修复主干
- 找到引入问题的提交,回滚或修复
- 主干修复后,其他开发者 rebase 最新代码再继续
Google 的做法是:谁搞坏了主干,谁负责修复。如果短时间内修不好,直接回滚。
5、与持续集成/持续部署的关系
TBD 和 CI/CD 是相辅相成的:
- CI(持续集成):TBD 要求频繁集成,CI 确保每次集成都通过自动化验证。
- CD(持续部署):主干始终可部署,每次提交都可以触发自动部署。
提交代码 → CI 检查 → 代码审查 → 合并到 main → 自动部署到生产
↑_______________________________________________|
整个过程自动化
实际上,TBD 是实现真正持续集成的前提条件。如果特性分支存在几周才合并,那只能叫”定期集成”,不是持续集成。
6、适用场景
TBD 适合以下场景:
- 大型团队、单一代码仓库:减少合并冲突,保持代码流动
- 成熟的 CI/CD 基础设施:有完善的自动化测试和部署流水线
- 微服务架构:每个服务独立部署,分支管理更简单
- 追求极致交付速度:高频发布,快速获取用户反馈
TBD 不太适合:
- 缺乏自动化测试的团队(主干很容易坏)
- 需要严格版本控制的客户端软件(如 SDK、App)
- 开源项目(外部贡献者无法直接提交到主干)
7、四种模型全景对比
| 维度 | Git Flow | GitHub Flow | GitLab Flow | TBD |
|---|---|---|---|---|
| 分支数量 | 多 | 少 | 中(按需) | 极少 |
| 分支寿命 | 数天到数周 | 数小时到数天 | 数小时到数天 | 数小时 |
| 发布节奏 | 固定周期 | 持续部署 | 两者皆可 | 持续部署 |
| 多版本支持 | ✅ | ❌ | ✅ | ❌(通过 Flag) |
| 学习成本 | 高 | 低 | 中 | 中 |
| CI/CD 要求 | 中 | 高 | 高 | 极高 |
| 典型用户 | 客户端软件 | Web 应用、开源 | GitLab 用户 | Google、Facebook |
8、总结
四种分支模型各有侧重,没有绝对的优劣:
- Git Flow:适合传统软件交付,规则明确但流程重。
- GitHub Flow:适合 Web 应用和持续部署,简单直接。
- GitLab Flow:在简洁和灵活之间取得平衡,按需扩展。
- Trunk-Based Development:最极致的持续集成,要求最强的工程纪律。
选择分支模型时,核心是看你的项目特点和团队能力:发布节奏是什么?是否需要维护多版本?CI/CD 基础设施是否成熟?团队规模多大?
没有银弹,只有最适合的选择。
每天前进一小步,就是一个新的高度!