DevOps,持续集成、持续交付,都是这几年火热的概念,也越来越深入人心。个人认为,所有这一切的基础,都是分支策略。
1 为什么需要分支策略
我们先考虑一下最”简单“的情况:所有的代码都是一个人开发,没有多人协作。所有的功能都是有序开发,每个版本都是开发完成,经过严格的设置,然后发布。并且在线上不会出现bug。这种情况下,其实是不需要分支策略的,甚至不需要分支,我们按部就班的开发、提交就可以了。
但是,这种最简单的情况在现实中是不存在的。因此也就出现了分支策略。可以说,分支策略是软件协作模式和代码发布模式的基础。
一位架构师前辈对我说过:”作为一个架构师,在学习的时候,不仅要知道怎么做,还要知道为什么这么做。不同的技术、不同的方案分别能够解决什么问题,又会带来什么问题。离开应用场景谈架构,都是耍流氓。”
因此,在详细讲解流行的分支策略之前,我们先看看在代码管理中,我们经常遇到的问题是什么。
- 第一版在测试的同时,开始下一版的并行开发。bug需要同时在两个版本中修复。
- 线上版本出现bug,需要快速修复,因此需要有线上发布的”纯净“版本。
- 多个历史版本需要同时维护,一个线上版本的bug修复,可能需要提交到多个历史版本以及开发版本中。
4.打乱计划,迭代中期要求快速上线部分新功能。
2 分支策略的分类
目前各个公司使用的分支策略各不相同,但是万变不离其宗,所有的分支策略,都可以归结为三种类型:
- 主干开发,分支发布
- 分支开发,主干发布
- 主干开发,主干发布
2.1 主干开发,分支发布
这种分支策略中,开发团队都将修改提交到主干分支,
主干开发,分支发布
在这种策略下,通常来说,所有的提交都是提交到主干。需要发布版本的时候,从主干上拉出发布分支,进行打包和最终的测试。注意这个分支是以发布为目的的,因此新功能不应该提交到该分支。在测试的过程中出现的bug,修复后仍然是提交到主干分支,然后从主干分支上采用cherry pick的方式合并到发布分支中。
发布分支测试完成后,发布到生产环境中。如果在生产环境中发现了bug,通常需要快速修复,这个时候可以在主干上修复,然后采用cherry pick的方式合并到发布分支上;也可以在发布分支上进行紧急修复,然后合并回master分支。具体选择哪一种,根据修复的紧急程度决定。如果可以,尽量采用主干提交,cherry pick合并到发布分支的方式。
这种分支策略的优点在于简单明了,易于理解。有利必有弊,这个模型对于主线代码质量要求高,如果某次提交出现了问题,那么会团队所有的后续提交都无法集成测试。另外,通常我们一个功能的开发过程中会有多次提交,多个功能的多次提交交错进行,就会导致当某个功能没有及时完成又必须上线的时候,上线版本中会包含未完成的功能,影响发布分支的代码质量。同时,所有直接提交到发布分支中的紧急修复,都必须合并回主干分支。这一点很容易被忘记。我们通常会采用以下的方法解决这些问题:
- 代码提交前进行code review,提高主干代码的质量。
- 采用功能开关配置(会带来配置复杂的问题)
- 专人负责将紧急修复反向合并到主干。
这种情况下,我们可以并行管理多个分支,可以进行快速的修复,通过分支合并的方式,将在多个分支中同时修复bug。 但是如果在开发中期需要快速上线功能,比较困难。
这种策略下,我们无法同时维护多个版本,但是可以支撑快速发布部分新功能,因为新特性互不干扰,没有交错提交的问题。
2.2 分支开发,主干发布
这种策略下,对于一个新的功能,会拉出一个新的分支,称为特性分支。在特性分支上进行该功能的开发和测试,通过后合并回主干,在主干进行回归测试。
如果粒度比较细的话,一个新特性就是一个分支。如果粒度粗一些,可以以一个模块,或者一个快速迭代为一个分支。这两者的区别在于特性分支存在的时间长短。
分支开发,主干发布
这种分支策略下,功能的开发比较独立,不会因为并行开发而受到干扰。同时这种实践需要特性拆分足够小,并且需要强大的测试环境支撑,最好有持续集成和自动化测试的支撑。
2.3 主干开发,主干发布
这种策略下,只有一条分支——主干分支。开发人员的代码直接提交到主干上,软件的发布也基于主干。因此,这种策略要求主干随时处于可发布的状态,从而要求每一次的代码提交都是非常高质量的。因此,在代码提交的时候,要有严格的代码审查,要有充足的自动化测试。每一次代码提交都会触发完整的编译构建、单元测试、代码扫描、自动化测试等过程。
这种策略能够解决什么问题呢,其实个人觉得前面提出的问题,一个的解决不了。这种策略的要求是把所有的问题消灭于萌芽前,不是治病而是”治未病“。这种策略带来的好处就是可以很好的支撑持续集成和持续交付,达到一天多次交付。
大道至简,这种策略就是最简单的策略,甚至可以说是没有策略,这个就是传说中的无招胜有招了。虽然很牛,但是不是每个公司都能够玩得转的,就像没有悟性是玩不转无招胜有招的。
2.4 分支策略小结
这3种策略各自适应不同的场景和要求,没有最好,只有最合适。而且,我们可以根据自己的需求进行裁剪合并,并不一定拘泥于其中的一种。我比较喜欢的策略就是**主干开发,分支发布 + 特性分支”的方式。
3 业界使用比较广泛的分支工作流程
目前业界的代码管理中,使用最广泛的就是git,使用最广泛的分支工作流程有:
- Git Flow
- GitHub Flow
- GitLab Flow
下面我们来详细的看看这3种流程。
3.1 Git Flow
下面是Git Flow的流程示意图。
Git Flow分支工作流程示意图
这张图猛一看有点乱,不太容易理解。这也是Git Flow的缺点之一:过于复杂。下面让我们来看看Git Flow的具体流程。
在Git Flow种,有很多分支,最主要的分支是Master分支和Develop分支。还有一个相对重要的分支是release分支。我们先来看看这3个分支之间的流程。
新的功能的开发,都在develop分支上提交。当满足发布条件的时候,从develop分支拉出release分支。如果有bug,则在release分支上进行修改和测试,bug修复过程种的每一次提交,都需要同步到develop分支上。当所有的bug修复,可以上线的时候,从release分支合并到master分支,并添加相应的版本tag。
还有两个分支,则是feature分支(特性分支)和hotfix分支。
Feature分支是从develop分支拉出的特性分支,相关特性的开发在特性分支上完成之后,再合并到develop分支。
Hotfix分支则用于修改线上的bug,hotfix分支的提交,最终都会合并回develop分支和master分支。合并到master分支的时候,也需要打版本标签。生产环境的发布,则从master分支来发布。
过于复杂和繁琐的流程,让现在使用git flow的公司越来越少。
3.2 GitHub Flow
GitHub Flow是完全的分支开发,主干发布。GitHub Flow种,只有master分支和特性分支。所有的代码都不能直接提交到master分支,而是提交到对应的特性分支,经过code review,测试后,再合并会master分支。这样,master分支随时处于可部署的状态。这么简单的流程,就不用画图了吧?实在要图,参考上面的分支开发,主干发布的图。
和Git Flow相反,GitHub Flow的最大的特点就是简单实用。但是需要有自动化测试、代码扫描的支持。
3.3 GitLab Flow
GitLab Flow其实是3个分支模型的总称,这3个模型如下表所示
分支模型 | 说明 |
---|---|
带生产分支 | 适用于无法控制准确的发布时间,但又要求不断集成的项目。创建了一个Product分支来放置已经发布的代码。 |
带环境分支 | 适用于要为不同的环境创建不同的分支的项目,所有的代码都要在逐个环境种测试通过 |
带版本分支 | 适用于需要并行维护多个版本的项目,bug的修改先合并到master,然后再cherry pick到各个发布分支 |
这三种分支模型的示意图分别如下面的三个图所示。
带生产分支 带发布分支 带版本分支的
4 总结
总而言之,一切的设计都是为了解决问题,因此在选择分支策略的时候,没有最好,只有最合适。我们需要根据自己的需要来选择分支策略,也可以从上面介绍的各自业界常用的策略种进行裁剪和调整,以适应我们自己的需求。
网友评论