文章目录
- 1. 前言
- 1.1 分支、发布 管理上解耦
- 2. 主干 (Trunk) 和分支 (Branch)
- 2.1 Trunk 开发 Trunk 发布
- 2.1.1 Trunk 开发 Trunk 发布需要解决:重构的需求
- 2.1.2 Trunk 开发 Trunk 发布需要解决:未开发完成的功能被带入发布版本
- 2.2 Trunk 开发 Branch 发布
- 2.2.1 Trunk 开发 Branch 发布较好的应用场景
- 2.2.2 Trunk 开发 Branch 发布需要解决:开发窗口期割裂
- 2.3 Branch 开发 Trunk 发布
- Branch 开发 Trunk 发布需要解决:冲突频出
- 3. 分支演进
- 3.1 三驾马车 分支模式
- 3.2 GitFlow 分支模式
- 3.3 GitHubFlow 分支模式
- 4. 发布模式
- 4.1 项目制发布模式
- 4.2 发布火车模式
- 4.3 城际快线
- 5. 怎么选分支模式和发布策略
- 5.1 为什么这么选?
- 5.1.1 业务上
- 5.1.2 代码管理上
- 5.1.3 技术更替上
- 5.1.4 流水线构建
- 5.2 其他选择
- 6. 后记
- 7. 参考
1. 前言
这本书扫盲了 “交付” 的方法论。之前工作过的公司都不会仅仅用一种方法。包括但不限于敏捷、极限编程。所有理论都是因地制宜的,公司往往不会是纯粹的xx理论遵循者,比如团队中既有 Scum master 角色(来自敏捷),也用 User Story 管理需求 (来自极限编程)。方法都是发展过来的,永远保持学习的心态。本文主要整理下书中出现的分支策略,并加以理解。如果分支策略更好的支持持续交付,则认为这种策略是有前景的。另外,分支策略的选择和发布方式也紧密相关,文章最后会给出个综合策略,以后会持续维护这篇文章,有更新的想法会更新到后记去。
1.1 分支、发布 管理上解耦
- 语义维度
- 主干可以发布到 UAT 环境 、预发环境、生产环境。
- 分支同样可以发布到以上的三种环境。
- 发布与分支质量相关
- 多久一次发布,会决定分支的存活时间,从而影响分支合入后的冲突情况。
把 分支、发布 管理分开来,有利于自由组合成公司理想的运作方式。
2. 主干 (Trunk) 和分支 (Branch)
-
Trunk
用这个单词表示主干,团队中可能也用master表示主干,这里用 Trunk 统一一下语义,不再提master -
Branch
区分于主干的其他分支,都称为 Branch
2.1 Trunk 开发 Trunk 发布
所有人都基于 Trunk 检出自己的私有分支,并且上线前合入 Trunk 。
2.1.1 Trunk 开发 Trunk 发布需要解决:重构的需求
该模式的明显缺点是,如果私有分支长时间未合入或者改动范围过大、则有可能再也合不进了。如 2011 年百姓网的失败案例:从 Trunk 检出重构的专有分支用于重构某个重要模块,但是一周后发现与当前 Trunk 冲突过多,最终放弃合入。
- 后文将提到抽象分支的管理技术,让重构更好落地
2.1.2 Trunk 开发 Trunk 发布需要解决:未开发完成的功能被带入发布版本
该模式另外一个缺点是,Trunk 发布前工程师不好提交其他迭代的代码,如果未经测试的代码被发布,安全隐患十分大。
- 后文将抽象分支、开关技术可以解决
2.2 Trunk 开发 Branch 发布
开发人员将写好的代码提交到 Trunk,当 Trunk 分支上的代码符合发布规范后,从 Trunk 检出一个 Branch 用于发布, Branch 上的 bugfix 都提交到自身上去,决定是否合入 Trunk 看是不是公用的功能。这么做的好处是,尽量不携带未开发完成的功能进行发布,同时 Branch 检出后,其他人还能在 Trunk 上面增量开发。
2.2.1 Trunk 开发 Branch 发布较好的应用场景
-
开源项目
没有发布时间的压力 -
系列化产品族 + 个性化定制
不同产品族的代码可能不需要再合入 Trunk
2.2.2 Trunk 开发 Branch 发布需要解决:开发窗口期割裂
Branch V1.0 要被检出用于发布前,Branch V2.0 是不好在 Trunk 上面增加代码的。V1.0 和 V2.0 的开开发窗口不能有重合。
2.3 Branch 开发 Trunk 发布
笔者(博客)所经历的公司都是用这种模式。每个特性都从 Trunk 检出一个 Branch ,每个Branch互不干扰。Branch 验收通过后,合入 Trunk,将 Trunk 发布。
Branch 开发 Trunk 发布需要解决:冲突频出
每个 Branch 互不干涉,并且上线前都不会合入 Trunk,两个 Branch 相继合入可能会发生冲突,并且冲突存在的时间可能已经很久了,解决起来会比较棘手。
3. 分支演进
上文提到了 Trunk 和 Branch 的区别,文章后文把 Trunk 和 Branch 的概念都融入进 “分支” 里了,比如发布分支其实指的就是上文的 Trunk。
3.1 三驾马车 分支模式
常用于客户端软件。开发 Branch 会把commit 都 cherry-pick 到 预发 Branch 上,在预发上进行bug修复等工作,修复完成后会把预发 Branch 依次发布为 Alpha 版本给极少的用户使用,Alpha验收完成后接着发布为 Beta版本。Beta验收通过后,把预发 Branch merge 进 发布分支。
3.2 GitFlow 分支模式
实质上是Develop 作为开发分支,Release 作为预发分支,Master 作为发布分支。是三驾马车的演进版本。新增的 Hotfix 用于支撑快速的bug修复,Feature 用于区分不同特性,让开发分支接收更频繁的合入,把冲突暴露到更早的时候。
-
Hotfix
直接从 Master 检出,解决bug后合入 Master 和 Develop -
Develop
所有特性分支的载体,同时保持 Hotfix 都要存在 ,避免特性分支检出的是带bug的代码。 -
Feature
从 Develop 检出并合入 Develop -
Release
Develop 中阶段性的所有 Feature 都达到可发布的状态,则检出一个 Release -
Master
用于发布 Release 或者接收 Hotfix
3.3 GitHubFlow 分支模式
是 Trunk 开发 Trunk 发布的落地方案。
比起 GitFlow ,这种方案简单不少。笔者(博客)在公司里主要也是用这种,直接从Master 检出多个Featrue 分支,Featrue 需要上线的话,提交 Pull Request,leader 控制 merge 这个 Request 后即可把 Master 发布了 (发布到UAT环境或者是PRODUCT环境)。
4. 发布模式
发布模式,是想体现什么指标完成后必须要发布一个版本。具体指标
- 项目制 (里程碑)
- 时间(迭代周期)
- 特性数
4.1 项目制发布模式
交付周期较长,参与的人较多。常常需要一个里程碑作为版本的描述,比如:“供应商入驻版本”。
4.2 发布火车模式
严格按照迭代周期走,一个月一个版本或者两周一个版本,无论迭代周期参生了多少个需求、特性。
4.3 城际快线
比发布火车更频繁,一周或者一天的迭代,所有特性都可以选择搭乘某一个 “快线” 进行发布。城际快线更符合持续交付2.0的思想。
5. 怎么选分支模式和发布策略
书中认为的最佳实践:
- GitHubFlow 分支模式 + 城际快线发布。
5.1 为什么这么选?
5.1.1 业务上
鼓励把需求拆分的很细,持续的与客户进行交流,了解客户的真实需求。得到的反馈越早,需求价值越高。
5.1.2 代码管理上
避免分支代码存在太久造成冲突无法解决。也避免分支层级过多造成管理上的困难 (如GitFlow多达5种的分支类型)
5.1.3 技术更替上
把重构任务分散到许多小的发布上,可以很好利用积少成多的特点把重构逐步完成,避免重构分支创建出来,经历的迭代太多而造成冲突无法合入主干,这也就是书中提到的 “抽象分支”。
5.1.4 流水线构建
有多少个环境就建立多少个流水线。
- Master 分支用于发布的,建立一条流水线 (1)
- Master 检出 Feature 分支
- 针对 Feature 分支 可以创建 SIT 的流水线 (2)
- 争对 Feature 分支 可以创建 UAT 的流水线 (3)
5.2 其他选择
笔者经历的其他实践:
-
GitHubFlow 分支模式 + 发布火车发布
需求都要集中验证的情况下,特别是迭代周期较长,只需要一个开发分支即可。 -
GitFlow 分支模式 + 城际快线发布
不同需求的迭代周期不同,则每个需求都会有一个开发分支。
6. 后记
分支、发布策略的组合都是管理者的考量,其实是各有特点的,不需要排斥。在至少有测试环境(UAT)、生产环境并存的情况下。笔者认为,在 GitHubFlow 分支模式下添加个用于测试环境流水线的 Dev分支更加合理。综上,笔者总结的策略如下:
- 一个 Master 分支用于发布线上环境
- 一个 Dev 分支用于发布到测试环境
- 基于 Master 检出多个 Feature 分支用于开发新功能 (迭代周期长可以多人共用一个Feature)
- 基于 Master 检出多个 Bugfix 分支用于紧急修复
- Feature 、Bugfix 分支要合入 Dev 并发布到测试环境验证
- Feature 分支验证通过后合入 Master 最终发布到线上环境
7. 参考
Git flow分支管理策略