4种常见分支模式解析

主干开发模式

image.png

团队人很少(比如1~2个人)的时候,最常见的研发模式是Trunk—BasedDevelopment,也叫主干开发方式。

主干开发方式一条主干分支走到底,开发的过程中不会有太多的冲突,要求代码持续集成到主干上去,所以在开发过程中不需要做相应工作的隔离。开发的过程中,所有的开发者在主干上面频繁地提交,频繁地集成。这种分支模式下,唯一的分叉出现在发布的时候,为了能够把发布版本隔离出来,有了发布分支。

这种模式下,不需要做分支隔离,信息同步通过持续频繁地提交来保证。在人数比较少,并且整个工程能力比较强的时候,这是我们推荐的研发模式。

但是当参与开发的人数越来越多时,主干开发的冲突几率就大大增加了,对工程能力的要求也越来越高。

所以说主干开发不是万能药,主干上的人越多,代码提交的冲突机率就越大,而且解决冲突的风险也越大。如果两个人的时候,即便有冲突我知道只是和另外一个人有冲突,如果是10个人,这中间就会产生很多的问题。

另外在主干开发里面,要保持信息地同步,需要做频繁持续地提交,而且每次提交的力度要很小,这针对有一些特性来说,可能只做了一半,这时需要将它提交上去,需要通过特性开关等方式来进行隔离。比如说这个是还未完成的特性,提前把它的开关制成Off,再做相应的提交,但是特性开关本质上也是一个分支。

特性开关只是用代码的形式拉了一个分支,但是这个分支只有打开的时候才能跑到,本质上还是一个分支。如果特性开关比较多,它在一定程度上会把代码变得很脆弱,维护起来比较麻烦。

主干开发当很多人同时参与时,代码冲突的机率很大,而且特性开发的时候也有很多的风险,大家彼此之间需要隔离。

Git-Flow模式

image.png
Git Flow 最开始是由 Vincent Driessen 发行并广受欢迎,这个模型是在 2010 年构思出来的,而现在距今已有 10 多年了,而 Git 本身才诞生不久。在过去的十年中,Git Flow 在许多软件团队中非常流行

分支命名规范:

master 分支:master 分支只有一个,名称即为 master 。GitHub 现在叫 main

develop 分支:develop 分支只有一个,名称即为 develop

feature 分支:feature/<功能名>,例如:feature/login,以便其他人可以看到你的工作

hotfix 分支:hotfix/日期,例如:hotfix/0104

分支说明

  • master || main 分支:存储正式发布的产品,master || main 分支上的产品要求随时处于可部署状态。master || main 分支只能通过与其他分支合并来更新内容,禁止直接在 master || main 分支进行修改。

  • develop 分支:汇总开发者完成的工作成果,develop 分支上的产品可以是缺失功能模块的半成品,但是已有的功能模块不能是半成品。develop 分支只能通过与其他分支合并来更新内容,禁止直接在 develop 分支进行修改。

  • feature 分支:当要开发新功能时,从 master 分支创建一个新的 feature 分支,并在 feature 分支上进行开发。开发完成后,需要将该 feature 分支合并到 develop 分支,最后删除该 feature 分支。

  • release 分支:当 develop 分支上的项目准备发布时,从 develop 分支上创建一个新的 release 分支,新建的 release 分支只能进行质量测试、bug 修复、文档生成等面向发布的任务,不能再添加功能。这一系列发布任务完成后,需要将 release 分支合并到 master 分支上,并根据版本号为 master 分支添加 tag,然后将 release 分支创建以来的修改合并回 develop 分支,最后删除 release 分支。

  • hotfix 分支:当 master 分支中的产品出现需要立即修复的 bug 时,从 master 分支上创建一个新的 hotfix 分支,并在 hotfix 分支上进行 BUG 修复。修复完成后,需要将 hotfix 分支合并到 master 分支和 develop 分支,并为 master 分支添加新的版本号 tag,最后删除 hotfix 分支。

提交信息规范
提交信息应该描述“做了什么”和“这么做的原因”,必要时还可以加上“造成的影响”,主要由 3 个部分组成:Header、Body 和 Footer。

Header Header 部分只有 1 行,格式为<type>(<scope>): <subject>

type 用于说明提交的类型,共有 8 个候选值:

  1. feat:新功能( feature )
  2. fix:问题修复
  3. docs:文档
  4. style:调整格式(不影响代码运行)
  5. refactor:重构
  6. test:增加测试
  7. chore:构建过程或辅助工具的变动
  8. revert:撤销以前的提交
  9. scope 用于说明提交的影响范围,内容根据具体项目而定。
  10. subject 用于概括提交内容。

Body 省略

Footer 省略

Git—Flow的基本原则是需要什么分支就给什么分支,任何事都有很明确的分支。比如说要集成,就有develop分支,要开发就有feature分支,要发布有release分支,每个都是不同的分支。每种类型的分支都有确定的用途。

比如说feature分支,是很多个feature并行开发的时候用来去做工作隔离,避免彼此之间有冲突。而release分支是用来做发布的隔离,使得发布之间不会有冲突。

我们发现这种模式很好地做了隔离,但是在信息同步的过程中,它需要基于develop频繁地集成去做同步,并且在各个分支中间做相应的cherry-pick或者是rebase这样的方式来做的。

这个时候,我们就会发现分支太多,而且一个commit从feature开发到最终发布要经历好几个分支,其中分支的流转和merge规则非常麻烦。

所以Git—Flow也不是仙丹,过多的分支增加了分支管理的复杂度。还有如果Feature分支的生命周期特别长,它的合并耗时也会变得很长。而且Develop分支和Master分支同时存在,好像Develop分支的意义不是特别大。另外区分Feature分支和hotfix好像意义也不是特别大。

所以Git—Flow虽然增加了很多的分支,让各种工作尽可能地隔离开来,但是它信息同步是很麻烦的,而且它管理这些分支的难度也特别大。

GitHub-Flow模式

image.png

GitHub引入了一个分支模式叫GitHub—Flow,明显比Git—Flow简单很多。没有Develop,没有hotfix,也没有Release,当需要开发的时候拉一个Feature分支,开发完就合并Master做发布。

这个过程中,它的隔离只发生在开发过程中,它的信息同步通过持续地往Master去做集成,和频繁从Master里面Pull代码来实现。它的发布过程是基于主干Master分支做的,因此没有在发布的过程中做相应地隔离。

这时候又会带来一个问题,就是Master分支需要做持续集成,这个分支既是集成的地方也是发布的地方。一旦集成后出现问题,它会把所有的工作堵塞掉,无法发布也无法合并。

所以GitHub—Flow很简单,可以做相应地隔离,但是如果说本身基础设施或工程能力比较弱,它会限制你集成和发布的频率。

GitLab-Flow模式

image.png

GitLab—Flow和GitHub—Flow区别是在发布过程中有了Pre-production分支和Production分支,基于开发、集成和发布过程中不同的环境分配了相应的分支。

完成集成以后是在Master分支上,下面一步将会切换到预发分支上。对应Commit的版本已经达到了预发的条件,在预发上做完验证以后再将其同步到Production分支,说明它已经达到了发布的条件,所以它是逐级Promotion(晋级)的过程。逐步从集成的环境Promotion到预发环境,再Promotion到生产环境。

我们简单地介绍了一些常见的分支模式,下面我们再来比较一下他们之间的优劣。

常见分支模式优劣对比

image.png

TBD分支少,实施简单,做起来不需要太多的理解成本。但是它对团队协作的成熟度和纪律都有很高的要求,一旦有人不遵守纪律,那主干就会成为你的梦魇,这时就很难很好地去做持续地集成和发布了。一旦它出现问题,所有人都被Block,这是主干方式的优缺点。

Git—Flow特性之间可以并行开发,规则很完善,每个分支的职责特别明确,再大的团队协作基本上也不会有太多的问题,但是它分支太多,规则太复杂,而且分支生命周期长,合并冲突会比较频繁。尤其是Develop,Master是长期存在的。

对于GitHub—Flow,Git—Flow能支持的基本上它也能支持,但是这里面有一个问题,它的集成只有在Master分支去做,因此对集成纪律有很高的要求,而且集成和发布在一个分支上,一旦集成分支中断,无论是集成还是发布都会被中断。

Gitlab—Flow也是并行开发,但是开发分支还是会有生命周期长的问题,有合并冲突的风险。另外,发布分支之间是有耦合的,比如说Prodution和Pre—Prodution之间,是基于Promotion来耦合,所以彼此之间也是一种中断阻塞的方式,而且很多的开发分支,Prodution和Pre—Prodution,也增加了分支管理的复杂性。

因此,我们发现没有哪个分支模式是绝对好的,也没有哪个是绝对差的。

对于分支有一个简单的原则,即控制分支数目,小批量频繁集成。控制分支的数目也就是做到工作隔离,但是又增加太多管理成本。而小批量频繁集成可以加速信息同步。

所以一个简单的原则就是,从最大化生产力和最小化风险的角度,尽可能地控制分支的数目和小批量频繁集成。

最大化生产力:所有人工作在公共区域内。除了一条长期的,不被中断的开发主干外,没有任何分支。也并无其他规则,代码的提交过程相当简单。但是,每一次的代码提交,都有可能破坏整个项目的集成,进而导致项目进度的中断。

最小化风险:所有人都工作自己的分支上。每个人的工作是相互独立的,没人可以打断其他人的工作,这样,减少了开发被打断的风险。但是,这种做法却增加了额外的流程负担,同时,协作变得非常困难,所有人都不得不谨小慎微地合并自己的代码,即便是整个系统中非常小的一部分,也是如此。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐