每个工程团队最终都会撞上同一面墙。你的 Git 历史记录看起来像一盘意大利面。合并的时间比功能开发本身还要长。发布日感觉就像在拆除炸弹。而在某个 Slack 频道里,一位开发者正在问:”这个热修复应该从哪个分支切出?”
根本原因几乎从来不是 Git 本身,而是工作流程——分支模型、合并策略,以及团队在推送代码时遵循(或忽略)的隐性规则。到了 2026 年,CI/CD 管道可以在几秒内运行,功能标志已集成到每个部署平台中,关于哪种 Git 工作流程真正有效的计算已经发生了显著变化。
本文将剖析三种主流的 Git 工作流程——主干开发(Trunk-Based Development)、GitFlow 和 GitHub Flow,并诚实地评估每种流程的优势和不足。没有理论上的空谈,只有从每种模型下已发布软件的团队中提炼出的实用指导。
简史:我们是如何走到这一步的
Vincent Driessen 在 2010 年 1 月发布了原始的 GitFlow 模型。在当时,这具有革命性意义。大多数团队仍在从 SVN 迁移,而带有 develop、release/*、hotfix/* 和 feature/* 分支的结构化分支理念,为组织提供了他们迫切需要的思维模型。
GitFlow 主导了近十年。但随着团队采用持续交付,裂缝开始出现。该模型假设离散的发布——版本 2.3、版本 2.4——这一假设与每天部署到生产环境数十次的团队相冲突。
GitHub Flow 作为一种更简单的替代方案出现:一个主分支、短暂的功能分支、拉取请求,以及合并时部署。它对 GitHub 本身以及发布 Web 应用的 SaaS 团队都非常有效。
主干开发(TBD)比两者都早。谷歌自 2000 年代初就在一个服务于数万名工程师的单一代码库中实践这种方法。但直到最近五年,随着工具的完善——功能标志变得廉价、CI 管道变得快速,以及可观测性使得在开关后面推送不完整代码变得安全——它才获得主流关注。
主干开发:细节解析
在主干开发中,每个人都向单个分支提交代码——通常是 main 或 trunk。没有长期存在的分支。如果存在短暂的功能分支,它们也只会持续几小时,而不是几天。
实际应用中的工作方式
开发者领取一个任务。他们拉取最新的 main 分支,进行修改,在本地运行测试套件,然后直接推送到 main 分支(或者打开一个存在时间很短的 PR,并在几小时内合并)。CI 管道在每次提交时运行。如果通过,代码就可以部署。功能标志控制未完成的功能。
# 典型主干开发工作流
git checkout main
git pull origin main
# 进行修改
git add -A
git commit -m "为 /api/v2/users 端点添加速率限制"
git push origin main
# 或者使用短期分支(同日合并)
git checkout -b sjy/rate-limit-users
# 进行修改、推送、打开 PR
# PR 在 2-4 小时内审查并合并
功能标志依赖
没有功能标志的主干开发是危险的。你需要一种方式来发布尚未准备好供用户使用的代码。到 2026 年,工具选择已经成熟:
- LaunchDarkly — 市场领导者,提供各种语言的 SDK,评估时间低于 50 毫秒
- Unleash 6.x — 最佳开源选择,可自托管,拥有完善的管理 UI
- Flipt 2.0 — 轻量级,原生支持 GitOps 的标志管理,将标志状态存储在你的仓库中
- PostHog Feature Flags — 与分析工具集成,可以直接衡量标志的影响
在 Node.js 服务中,实际的模式如下所示:
// 使用 Unleash 客户端
const { isEnabled } = require('unleash-client');
app.get('/api/v2/users', async (req, res) => {
if (isEnabled('rate-limit-v2-users', { userId: req.user.id })) {
await rateLimiter.check(req);
}
// 现有处理逻辑
const users = await userService.list(req.query);
res.json(users);
});
谁成功使用了主干开发
Google 在其单体仓库中通过单一主干运营了二十多年。他们的内部工具 Critique 处理对主干提交的代码审查。根据他们 2023 年的工程实践报告,超过 60,000 名工程师向单个仓库提交代码。
Spotify 在多年使用小队模型的长生命周期功能分支后,于 2020 年左右转向主干开发。这一转变与迁移到由 Bazel 管理的单体仓库同时进行。构建时间从 15 分钟以上缩短到受影响目标不到 3 分钟,使得频繁向主干提交变得可行。
Meta (Facebook) 为其 Web 单体仓库运行主干开发。工程师推送到主干,一个复杂的自动化金丝雀部署和功能标志系统决定了什么内容会到达生产环境。
GitFlow:完整图景
GitFlow 使用五种分支类型:main(生产环境)、develop(集成)、feature/*(新功能)、release/*(稳定化)和 hotfix/*(紧急修复)。其流程在设计上是严格的——这既是它的优势也是它的劣势。
分支结构
main ─────────●──────────────●──────────── (标记的版本)
/
release/2.4 ────●──●──●───●
/
develop ──●──●──●──●──●──●──●──●──●──●──
/ /
feature/A ●──● /
feature/B ●──●──●
GitFlow 真正适用的场景
当你的发布模型需要 GitFlow 时,它就能发挥作用。具体场景如下:
- 具有应用商店审核周期的移动应用。 你无法在10分钟内将修复部署到生产环境。你需要一个发布分支,让QA可以稳定4.7.2版本,同时开发人员继续开发4.8版本的功能。
- 嵌入式软件和固件。 当你的代码在物理设备上运行时,你需要带有明确切点的版本化发布。
- 客户自行部署的企业软件。 如果客户在本地运行你的软件并每季度升级一次,GitFlow 为你提供了支持多个维护版本的发布分支结构。
- 有审计要求的监管行业。 医疗保健、金融和航空航天团队有时需要一个正式的发布稳定阶段,以符合合规检查点。
GitFlow 的真正问题
合并冲突是残酷的。当 feature/A 和 feature/B 都运行两周并触及重叠代码时,合并到 develop 分支就变成了一场谈判。我曾见过团队在”合并派对”中花费整天时间解决冲突——这个术语听起来很有趣,除非你经历过一次。
分支开销不容小觑。开发人员必须记住从哪个分支切出、合并到哪个分支,以及何时创建发布分支。新团队成员经常搞错。在 GitKraken 2024 年的一项调查中,43% 使用 GitFlow 的团队将”分支混乱”列为最主要的摩擦点。
CI/CD 管道变得复杂。你需要为 develop、release/*、main 和 hotfix/* 分支分别配置管道。每个分支都有不同的部署目标和测试套件。典型的 GitFlow Jenkinsfile 或 GitHub Actions 工作流比基于主干(trunk-based)的等效流程长 3-4 倍。
具体案例:金融科技公司的移动团队
我在2024年底咨询的一家支付公司对其 iOS 和 Android 应用使用 GitFlow。他们的发布节奏是双周一次。工作流程如下:
- 第1-8天:在
develop分支的feature/*分支上进行功能开发 - 第9天:从
develop分支切出release/3.12 - 第9-12天:在发布分支上进行QA测试。错误修复提交到
release/3.12 - 第12天:将
release/3.12合并到main,打上v3.12.0标签,提交到App Store - 第13天:将
release/3.12合并回develop
这种方法奏效了。不是因为GitFlow本身有多好,而是因为外部约束(App Store审核)强制了一个发布稳定窗口,而GitFlow恰好自然地模拟了这一过程。主干开发需要更复杂的功能标志和发布列车设置才能实现同样的结果。
GitHub Flow:中间地带
GitHub Flow将一切简化为两个概念:main分支始终保持可部署状态,所有工作都在通过拉取请求合并的短期分支上进行。
工作流程
# 1. 创建分支
git checkout -b add-search-filters
# 2. 提交更改
git add .
git commit -m "为搜索API添加日期范围过滤器"
git push -u origin add-search-filters
# 3. 创建拉取请求
gh pr create --title "为搜索API添加日期范围过滤器"
--body "关闭#1234。添加start_date和end_date参数。"
# 4. 审查、讨论、迭代
# 5. 合并到main(通常是压缩合并)
gh pr merge --squash
# 6. 部署(通过CI/CD自动进行)
GitHub Flow vs. 主干开发:细微差别
GitHub Flow和主干开发之间的界限很模糊。关键区别在于:GitHub Flow将拉取请求作为一流的工作流程步骤。主干开发纯粹主义者认为PR会拖慢速度,结对编程或提交后审查更可取。
实际上,2026年大多数团队运行的是介于两者之间的模式:短期分支(1-3天),强制PR审查,压缩合并到main,以及合并后自动部署。你称之为”GitHub Flow”还是”带短期分支的主干开发”,这基本上只是命名之争。
直接对比
| 因素 | 主干开发 | GitFlow | GitHub Flow |
|---|---|---|---|
| 分支生命周期 | 小时(或无) | 天到周 | 1-3天 |
| 合并冲突频率 | 非常低 | 高 | 低 |
| CI/CD复杂度 | 简单(一个分支) | 复杂(5种分支类型) | 简单(主分支+PR) |
| 发布模型 | 持续 | 版本化 | 持续 |
| 需要功能标志 | 是 | 否 | 有时 |
| 最佳团队规模 | 任何(借助工具) | 10-50 | 2-30 |
| 入门难度 | 低 | 高 | 低 |
| 支持多生产版本 | 否(需要额外工具) | 是(发布分支) | 否 |
| 回滚策略 | 功能标志切换 | 回滚合并或热修复分支 | 回滚提交 |
决策框架:选择合适的工作流程
选择主干开发时:
- 你每天部署到生产环境多次
- 你的CI流水线运行时间少于10分钟
- 你拥有(或愿意投资于)功能标志基础设施
- 你的团队有强大的自动化测试覆盖率(关键路径上80%+的行覆盖率)
- 你实践持续交付或持续部署
选择GitFlow时:
- 你发布版本化软件(移动应用、桌面应用、固件、SDK)
- 客户同时运行你的软件的不同版本
- 监管要求规定正式的发布稳定阶段
- 你的部署流水线缓慢或涉及外部把关(应用商店、合规审查)
选择GitHub Flow时:
- 你是小型到中型团队(2-30名工程师),正在构建Web应用或API
- 你希望通过拉取请求进行代码审查,但不需要版本化发布
- 你合并到
main时进行部署 - 你希望简单性,而不需要严格主干开发的功能标志开销
迁移案例:实际发生的情况
从GitFlow到主干开发:一个SaaS平台(120名工程师)
一家可观测性领域的B2B SaaS公司在2024年第三季度从GitFlow迁移到主干开发。他们内部回顾的关键数据:
- 合并冲突解决时间:从每位开发者每周4.2小时降至每周0.6小时
- 变更前置时间:从8天减少到1.5天
- 部署频率:从每两周一次增加到每天15-20次
- 变更失败率:最初从3%上升到7%,然后在功能标志实践成熟后稳定在2.8%
迁移花了4个月时间。第一个月用于设置 LaunchDarkly 并编写标志卫生指南(命名约定、标志的 TTL、清理流程)。第二个月是并行运行期,两种工作流程共存。第三和第四个月专注于迁移剩余团队,并停用 develop 和 release/* 分支约定。
最困难的部分不是技术层面,而是文化层面。已经内化了 GitFlow 心理模型的高级工程师们抵制这一变化。一位团队负责人将其描述为”直接提交到主分支感觉太鲁莽”。但在看到 CI 管道在生产环境前捕获问题两周后,这种不适感消失了。
从 GitHub Flow 到 GitFlow:一个移动 SDK 团队
相反方向上,一家开发者工具公司在2025年初将其移动 SDK 团队从 GitHub Flow 切换到 GitFlow。原因:他们需要同时维护 SDK 4.x、5.x 和 6.x 版本,因为他们的客户(移动应用开发者)无法立即升级。
GitHub Flow 没有用于长期存在版本分支的机制。他们尝试通过 cherry-pick 维护独立的 v4、v5 和 v6 分支,但当每月需要应用30多个补丁时,cherry-pick 的开销变得不可持续。
GitFlow 的发布分支模型——针对他们的多版本需求进行了适当调整——为他们提供了一种结构化的方式来稳定发布,同时继续下一个主要版本的开发。
2026 年带来差异的工具
你选择的工作流程不如围绕它的工具重要。以下是高性能团队正在使用的工具:
- 合并队列(GitHub、GitLab 17.x):在合并前自动 rebase 和测试 PR。消除了”在我的分支上能工作”的问题。GitHub 的合并队列功能自2023年正式发布以来,已成为基于主干团队的标配。
- 堆叠差异(Graphite、Gerrit、ghstack):将大型变更分解为可审查的、依赖关系的 PR。特别是 Graphite 获得了广泛采用——他们的 CLI(
gt)与 GitHub 集成,使堆叠 PR 变得易于管理。 - 合并前 CI(Buildkite、GitHub Actions):在每次合并前对每个 PR 运行完整测试套件。借助 ARM64 托管运行器(GitHub Actions
arm64-ubuntu-latest),计算密集型管道的构建时间已减少30-40%。 - Git absorb:一个开源工具(
git absorb),自动将 fixup 提交修正到堆栈中的正确父提交。对于保持堆叠差异的整洁至关重要。
实用技巧,无论工作流程如何
- 保持分支的生命周期短暂。 数据很明确:超过3天的分支会产生指数级增长的合并冲突。2025年DORA报告发现,精英团队的分支生命周期中位数为0.8天。
- 自动化分支清理。 配置GitHub/GitLab在合并时删除分支。运行每周的cron任务,清理超过30天的陈旧远程分支。
- 使用约定式提交。 无论你选择
feat:、fix:、chore:前缀还是自己的约定,一致的提交消息能够实现自动化变更日志和语义化版本控制。 - 保护你的主分支。 要求状态检查,强制线性历史(压缩或变基合并),并至少需要一次批准。在任何工作流程中这都是不可协商的。
- 衡量你的DORA指标。 跟踪部署频率、变更前置时间、变更失败率和平均恢复时间。这四个数字能告诉你你的工作流程是否真正有效。
总结
没有普遍”最佳”的Git工作流程。只有与你团队的部署模型、发布限制和工程文化相匹配的工作流程。
如果你持续部署并可以投资功能标志,主干开发可以消除大量的分支开销和合并痛苦。如果你向客户发布版本化软件,而客户控制他们的升级时间表,那么GitFlow——尽管有其复杂性——能为你提供所需的结构。如果你是一个构建网络产品的小团队,GitHub Flow在简单性和代码审查纪律之间达到了完美的平衡点。
大多数团队犯的错误是根据Google或Facebook的做法选择工作流程,而没有考虑到这些公司有数千名工程师构建自定义工具来使其工作流程可行。从你的限制开始——发布模型、团队规模、部署管道——然后逆向推导出最合适的简单工作流程。
无论你选择什么,每12个月重新审视一次。团队会成长,产品会演变,适合8名工程师的工作流程在40名工程师下将会崩溃。目标不是找到完美的工作流程。而是找到当前摩擦最小的工作流程,并在它停止工作时保持愿意改变的姿态。
