148 lines
10 KiB
Markdown
148 lines
10 KiB
Markdown
# 04 | 一切的源头,代码分支策略的选择
|
||
|
||
记得大概是一年前吧,我与好友老吴喝茶聊天时,讨论到:高效的持续交付体系,必定需要一个合适的代码分支策略。
|
||
|
||
我告诉老吴:“采用不同的代码分支策略,意味着实施不同的代码集成与上线流程,这会影响整个研发团队每日的协作方式,因此研发团队通常会很认真地选择自己的策略。”
|
||
|
||
老吴是一名有多年开发经验的资深架构师,当时正好要接手一个框架团队,从个人贡献者向团队管理者转型。他个人对代码管理工具可谓熟之又熟,甚至连“老古董”的CVS都可以跟你聊半天。但他在为团队制定代码分支管理策略时,还是慎之又慎,足见其重要性。
|
||
|
||
最后我们发现,要确定选用哪种代码分支管理策略,需要先假设几个问题,这几个问题有了答案,也就代表你找到了适合的方向。
|
||
|
||
你需要思考的几个问题如下:
|
||
|
||
1. Google和Facebook这两个互联网大咖都在用主干开发(Trunk Based Development,简称TBD),我们是不是也参照它俩,采用主干开发分支策略?
|
||
|
||
2. 用Google搜索一下,会发现有个排名很靠前的分支策略,叫“A successful Git branching model”(简称 Git Flow),它真的好用吗?团队可以直接套用吗?
|
||
|
||
3. GitHub 和 GitLab 这两个当下最流行的代码管理平台,各自推出了 GitHub Flow 和 GitLab Flow,它们有什么区别?适合我使用吗?
|
||
|
||
4. 像阿里、携程和美团点评这样国内知名的互联网公司,都在用什么样的分支策略?
|
||
|
||
|
||
今天,我想再沿着当时的思考路径,和你一起回顾和总结一下,希望能够带你全面了解代码分支策略,帮助你做出合适的选择。
|
||
|
||
## 谈谈主干开发(TBD)
|
||
|
||
**主干开发是一个源代码控制的分支模型,开发者在一个称为 “trunk” 的分支(Git 称 master) 中对代码进行协作,除了发布分支外没有其他开发分支。**
|
||
|
||
Google和 Facebook都是采用“主干开发”的方式,代码一般直接提交到主干的头部,这样可以保证所有用户看到的都是同一份代码的最新版本。
|
||
|
||
**“主干开发”确实避免了合并分支时的麻烦,因此像Google这样的公司一般就不采用分支开发,分支只用来发布。**
|
||
|
||
大多数时候,发布分支是主干某个时点的快照。以后的改Bug和功能增强,都是提交到主干,必要时 cherry-pick (选择部分变更集合并到其他分支)到发布分支。与主干长期并行的特性分支极为少见。
|
||
|
||
由于不采用“特性分支开发”,所有提交的代码都被集成到了主干,为了保证主干上线后的有效性,一般会使用特性切换(feature toggle)。特性切换就像一个开关可以在运行期间隐藏、启用或禁用特定功能,项目团队可以借助这种方式加速开发过程。
|
||
|
||
特性切换在大型项目持续交付中变得越来越重要,因为它有助于将部署从发布中解耦出来。但据吉姆 · 伯德(Jim Bird)介绍,特性切换会导致代码更脆弱、更难测试、更难理解和维护、更难提供技术支持,而且更不安全。
|
||
|
||
他的主要论据是,将未经测试的代码引入生产环境是一个糟糕的主意,它们引发的问题可能会在无意间暴露出来。另外,越来越多的特性切换会使得逻辑越来越混乱。
|
||
|
||
**特性切换需要健壮的工程过程、可靠的技术设计和成熟的特性切换生命周期管理**,如果不具备这三个关键的条件,使用特性切换反而会降低生产力。
|
||
|
||
根据上面的分析,主干开发的分支策略虽然有利于开展持续交付,但是它对开发团队的能力要求也更高。
|
||
|
||
主干开发的优缺点如表1所示。
|
||
![](https://static001.geekbang.org/resource/image/59/5e/59096cdc19f9e0a5fefbe99f9b57445e.png)
|
||
|
||
表1 主干开发的优缺点
|
||
|
||
## 谈谈特性分支开发
|
||
|
||
和主干开发相对的是 “特性分支开发” 。在这个大类里面,我会给你分析Git Flow、GitHub Flow和 GitLab Flow这三个常用的模型。
|
||
|
||
**第一,Git Flow**
|
||
|
||
我们在Google上查关键词“branch model”(也就是“分支模型”),有一篇排名比较靠前的文章“A successful Git branching model”,它介绍了Git Flow模型。
|
||
|
||
Git刚出来的那些年,可参考的模型不多,所以Git Flow模型在2011年左右被大家当作了推荐的分支模型,至今也还有项目团队在使用。然而,Git Flow烦琐的流程也被许多研发团队吐槽,大家普遍认为hotfix和 release 分支显得多余,平时都不会去用。
|
||
|
||
![](https://static001.geekbang.org/resource/image/4b/0f/4bc4c4035857479b2126fed5af4ce90f.png)
|
||
|
||
图1 Git Flow示意图
|
||
|
||
**第二,GitHub Flow**
|
||
|
||
GitHub Flow 是 GitHub 所使用的一种简单流程。该流程只使用master和特性分支,并借助 GitHub 的 pull request 功能。
|
||
|
||
![](https://static001.geekbang.org/resource/image/7a/14/7ae8a5fe4f5fcdae7ba9cfaf758f1a14.png)
|
||
|
||
图2 GitHub Flow示意图
|
||
|
||
**在 GitHub Flow 中,master 分支中包含稳定的代码,它已经或即将被部署到生产环境。任何开发人员都不允许把未测试或未审查的代码直接提交到 master 分支。对代码的任何修改,包括Bug 修复、热修复、新功能开发等都在单独的分支中进行。不管是一行代码的小改动,还是需要几个星期开发的新功能,都采用同样的方式来管理。**
|
||
|
||
当需要修改时,从 master 分支创建一个新的分支,所有相关的代码修改都在新分支中进行。开发人员可以自由地提交代码和提交到远程仓库。
|
||
|
||
当新分支中的代码全部完成之后,通过 GitHub 提交一个新的 pull request。团队中的其他人员会对代码进行审查,提出相关的修改意见。由持续集成服务器(如 Jenkins)对新分支进行自动化测试。当代码通过自动化测试和代码审查之后,该分支的代码被合并到 master 分支。再从 master 分支部署到生产环境。
|
||
|
||
GitHub Flow 的好处在于非常简单实用,开发人员需要注意的事项非常少,很容易形成习惯。当需要修改时,只要从 master 分支创建新分支,完成之后通过 pull request 和相关的代码审查,合并回 master 分支就可以了。
|
||
|
||
**第三,GitLab Flow**
|
||
|
||
上面提到的GitHub Flow,适用于特性分支合入master后就能马上部署到线上的这类项目,但并不是所有团队都使用GitHub或使用pull request功能,而是使用开源平台GitLab,特别是对于公司级别而言,代码作为资产,不会随意维护在较公开的GitHub上(除非采用企业版)。
|
||
|
||
GitLab Flow 针对不同的发布场景,在GitHub Flow(特性分支加master分支)的基础上做了改良,额外衍生出了三个子类模型,如表2所示。
|
||
![](https://static001.geekbang.org/resource/image/0e/34/0efbe615c847aac070fdb9b8a588a434.png)
|
||
|
||
表2 GitLab Flow 的三个分支
|
||
|
||
![](https://static001.geekbang.org/resource/image/8e/1e/8e29bb4314de4492977e919abe91191e.jpg)
|
||
|
||
图3 带生产分支的GitLab Flow
|
||
|
||
![](https://static001.geekbang.org/resource/image/bd/c8/bd6218d57b6d522844cf080d9ca9a7c8.jpg)
|
||
|
||
图4 带环境分支的GitLab Flow
|
||
|
||
![](https://static001.geekbang.org/resource/image/1b/58/1bf962fe8b0523fefac348529ffc0d58.jpg)
|
||
|
||
图5 带发布分支的GitLab Flow
|
||
|
||
GitLab Flow的特性分支合入master用的是“Merge Request”,功能与GitHub Flow的“pull request”相同,这里不再赘述。
|
||
|
||
通过Git Flow、GitHub Flow和 GitLab Flow(3个衍生类别) 这几个具体模型的介绍,我给你总结一下特性分支开发的优缺点。如表3所示。
|
||
|
||
![](https://static001.geekbang.org/resource/image/a5/b1/a517f2b1c48c8de54e500df3996628b1.png)
|
||
|
||
表3特性分支开发的优缺点
|
||
|
||
## 选出最适合的分支策略
|
||
|
||
上面我跟你讲到的分支模型,都是IT研发领域比较流行的。虽然有些策略带上了代码平台的标识,如GitHub Flow,但并不意味着该策略仅限于GitHub代码平台使用,你完全可以在自己搭建的代码平台上使用这些策略。
|
||
|
||
接下来,我就总体归纳一下什么情况下应该选择什么样的分支策略。如表4所示。
|
||
![](https://static001.geekbang.org/resource/image/ae/d9/ae29f0b5a96306f49ce485c1823b23d9.png)
|
||
|
||
表4 不同情况适用的代码分支策略
|
||
|
||
## 国内互联网公司的选择
|
||
|
||
GitLab作为最优秀的开源代码平台,被多数互联网大公司(包括阿里、携程和美团点评等)所使用,这些大厂也都采用特性分支开发策略。当然,这些大公司在长期持续交付实践中,会结合各自公司的情况做个性化的定制。
|
||
|
||
比如,携程公司在GitHub Flow的基础上,通过自行研发的集成加速器(Light Merge)和持续交付Paas平台,一起完成集成和发布。
|
||
|
||
再比如,阿里的AoneFlow,采用的是主干分支、特性分支和发布分支三种分支类型,再加上自行研发的Aone协同平台,实现持续交付。
|
||
|
||
## 总结
|
||
|
||
今天,我主要给你介绍了各种代码分支策略的特性。
|
||
|
||
你应该已经比较清晰地理解了“主干开发”和“特性分支开发”两种策略的各自特性:
|
||
|
||
1. “主干开发”集成效率高,冲突少,但对团队个人的开发能力有较高要求;
|
||
|
||
2. “特性分支开发”有利于并行开发,需要一定的流程保证,能保证主干代码质量。
|
||
|
||
|
||
相信在没有绝对自信能力的情况下,面对绝大多数的场景,企业还是会选择“特性分支开发”的策略。所以,我给你介绍了几种主流的特性分支方法,并对比了各类策略的优劣,以及它们适用的场景。
|
||
|
||
接下来,你就可以根据自己所在项目的具体情况,参考今天的内容,裁剪出最适合自己团队的分支策略了。
|
||
|
||
## 思考题
|
||
|
||
1. 开源性质的项目,为什么不适合用主干开发的分支策略?
|
||
|
||
2. 如果你所在的团队只有5人,而且迭代周期为1周,你会采用什么样的分支策略?
|
||
|
||
|
||
欢迎你给我留言。
|
||
|