常见分支模式优劣对比|学习笔记

简介: 快速学习常见分支模式优劣对比

开发者学堂课程【ALPD 云架构师系列-云原生 DevOps36计常见分支模式优劣对比】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/82/detail/1283


常见分支模式优劣对比

 

内容介绍:

一、常见的分支模式

二、常见分支的优劣性

 

上节课我们提了一个问题:如果说是一个人做软件开发用什么样的分支模式?

如果只有一个人,那么就不会有冲突,同时也不需要很多分支。比如说一个人做开发不需要彼此等待信息,所以说一个人在做软件开发其实很简单,因为基本上做一个分支就可以,也就是一条主干走到底。如果人数扩张到10人,100人就不一样。假如只有两个人,两个人协作的话,其实彼此之间也会有工作的一些隔离,那么可能也会存在冲突跟等待,但两个人的话,即便存在问题也能马上处理好,两个人讨论商量之后基本上就能解决这些冲突。所以说在这个过程当中,随着协作的人数增加,分支的模式会发生不断的一些变化。

 

一、常见的分支模式

 image.png

如果说只有一个人或者两个人,也就是人很少。那么常见的一种开发方式叫做Trunk-Based-Development ,也就是主干开发方式,主干开发方式很简单,就是一条主干走到底,也就是说开发的过程当中,它不会有太多的冲突,它是持续的集成到主干上去的。所以说在开发过程当中,它不需要做相应的一些工作隔离,所以开发中间其实是所有的开发者在上面频繁的提交,频繁的集成。这里唯一给出的一个隔离,是 release 隔离,也就是说针对一个代码基线,可能发布的版本不一样,为了把版本之间能够尽可能的隔离开,就有了一个发布的分支。同时它是在主干上进行频繁的持续的集成代码的信息同步的,所以在TBD模式里不需要做相应一些分支的隔离,它的信息同步是通过持续频繁的提交来保持信息的同步,那么在人数比较少并且公事能力比较强的时候可以用这个方法。

主干开发不是银弹

参与开发的人数增加了主干开发的冲突机率

参与在主上的人员越多,代码提交冲突的机率越大。

对于一些处在开发过程中的特性,如每次变更提交,并非意味着完整特性的完成,为了隔离“特性半成品”对主干的影响,一般会采用特性开关( FeatureToggle )的方式进行隔离。即频繁的代码变更提交,可以先做集成及验证,但是在发布的角度,通过( Feature Toggle)先隐藏相关特性,只有当特性都完成之后,才打开开关,特性完全透出。

但是,特性开关的引入也并不是没有成本,因为特性开关是配置,本质上跟我们常常用到的宏定义(#if #else)没啥区别,从本质上,它也是一种代码的分支。特性开关的使用,在一定程度上让你的代码变得更脆弱。

但是随着这个8个人慢慢变成了80个人的时候,我们发现开发的人数越来越多了,因为参与开发的人数增加,它就增加了主干开发的一个冲突几率。所以说主干开发并不是银弹,而且解决冲突的风险也越来越大,比如如果只有两个人,即便有冲突,那么就会知道冲突是跟对方的,如果十个人的时候,那这个中间可能会产生很多问题,另外,在主干开发提到一点,就是要保持信息的同步,需要持续频繁的提交,而且每次提交的力度很小。这就会针对一些特性,比如它可能只做了一半成品,这个时候你就要把它提交上去。那这个时候一般会通过特性开关的方式来进行隔离,说这个是还没完成的一个特性,先把它的开关制成 off 。然后再做相应的提交,但是特性开关其实本质上也是一个分支,就是说用代码的形式拉了一个分支,这个分支一般不会跑,只有把它打开才会,所以本质上还是一个分支。而且一个特性开关如果用的特别多,它在一定程度上会把你的代码变得很脆弱,维护起来也会特别麻烦。

这个时候就会想,如果主干开发的时候很多人在上面,那么冲突几率就会很大,而且本身特性开发的时候也会有很多风险,所以大家彼此之间要去隔离,那么这个时候引入了另外一种分支方式。让每个人有自己的分支,这样就会很好。

所以来看下一种模式:

 image.png

上图是 Git-Flow 分支方式,它的工作方式是,我觉得需要什么分支,他就给到什么分支,比如说要做集成就给 Devolop 分支,要做开发就给 feature 分支,做发布就给 release 分支。每个都是不同的分支。然后每一个分支都是有确定的功用的,比如说 feature 分支是很多个 feature 并行开发的时候去做相应的一些工作隔离以免彼此之间会有冲突的,而 release 分支是用来做发布的隔离,使发布之间不会有相应的一些冲突。那么在这个过程当中,他就很好的做好了隔离,但是它在信息同步的过程当中是以 develop 分支来频繁的集成来进行信息同步的。

并且会在各个分支之间做相应的一些同步的,那么在要去同步的时候,就会发现很麻烦。因为分支越来越多,而且一个 commit 从 feature 开发到最终发布要经历好几个分支,这个分支的流转跟 merge 规则其实是非常麻烦的。尤其是针对对 git 不太熟的人来说,他发现自己要去管理,要去理解的概念特别多。

所以 Git-Flow 也不是仙丹,过多的分支增加的分支管理复杂度,另外一个就是如果 feature 分支生命周期特别长。那么它的合并就会是一个噩梦,如果我拉了一个 feature 分支,在我开发了一年后想合定 develop 。那么可能要过一个月或两个月的时间才能合并进去。

另外,这里有 develop 分支,也有 master 分支,然后发现好像 develop 分支的意义不是特别大,同样 feature 分支和 hot fixes分支的意义也不是特别大。

所以说这里头其实我们发现 Git-Flow 虽然增加了很多分支,让各种工作尽可能的隔离,但是它信息同步很麻烦,而且它本身之间要去管理这些分支的难度也特别大。

image.png

这时引入了一个分支方式叫 Github-Flow ,这个明显比 Git-Flow 简单很多。没有 develop,release,hotfix 等分支。只有一个 feature 分支,需要开发的时候,就拉一个 feature 分支。开发完之后就合并到 master 分支做发布。

所以在这个过程当中它的隔离只是在开发过程当中的隔离,它的信息同步是持续的,往 master 去做集成的时候就会做信息同步,还有另外一个频繁的从 master 来 pull 代码合到 feature 分支来去做同步,这个时候它的发布过程是基于主干发布,也就是没有在发布的过程当做相应一些隔离。

这个时候又会带来一个问题,Master 是一个需要做持续集成的地方,也是发布的地方。这个时候一旦集成失败了,之后所有的工作都会阻塞,也就无法发布,同时也不能进。所以这个时候我们发现 github-flow 很简单,它可以做的相应一些隔离,但是如果说本身的基础设施或者工程能力比较弱的话,它也会限制整个集成或者发布的一个频率。

 image.png

这个时候我们看另外一个分支方式: gitlab-flow,gitlab-flow 和 Github-flow 唯一的区别就是在发布过程当中,它有一个叫做 pre-production 和 production 的分支,它基于在集成和发布过程当中不同的环境来给了他相应的一些分支。

在我完成集成之后,其实我是在 master分支上的,但这时候,下一步我会先把它拉到 pre-production 分支,也就是预发的分支上。就是这个 commit 版本已经达到了进入预发的条件,那在预发上做完验证之后。就可以把它再拉到 product 的工程上,就说明它已经达到了发布的条件了,所以它是一个逐级的promoting 过程,逐步从一个集成的环境到一个预发环境,再到一个生产环境。

 

二、常见分支的优劣性

比如说 TBD 它的分支少,然后实践简单,小步快跑,做起来非常简单,也不需要太多理解成本。

但是对团队的协作成熟度和纪律都有很高的要求,一但有人不遵守纪律,那这个主干就会成为你的梦魇。那这个时候就很难的很好的去做持续的集成或者发布了,也就没有一个就说可用的主干,因为 master 是一个公共的地方,这个时候一旦它出现了问题,所有人都会 block 。这就是主干方式的一个优缺点。

再看git-flow,特性之间可以并行开发,规则完善,每个分支的职责特别明确,支持复杂大团队的协作,基本上也不会太多的问题。但是分支太多,规则的太复杂,而且分支生命周期长,合并冲突会比较频繁。尤其像 develop,master 是长期存在的,对从哪合到哪是个非常麻烦的事,比如说 fixes,它可以直接进到 master ,但是它还要合进 develop。

看 github-flow,gitflow 可以支持的它也是支持的,但是这里会有一个问题,就是说因为它的集成只是有一个 master 分支来去做,这里对集成纪律有很高的要求,而且集成和发布它其实是在一个分支上,那这个时候你一旦集成分支中断了,所有不论是集成还是发布都会被中断。

最后说 gitlab-flow,它也可以支持并行开发,但是开发分支也有生命周期长的问题,那么也会有合并的冲突风险,另外发布分支之间是有耦合的,比如说 pre-production 和 production这样的分支之间是基于 promote 这种方式来进行耦合,所以这也是彼此之间的一种中断阻塞的方式。

另外,因为 pre-production 和 production 其实也引入了分支管理的这种复杂性。所以说从这些角度来说,我们会发现没有哪个方式是绝对好的或者说哪一个是绝对差的。

所以说其实有一个简单的原则,就是说要去控制分支的数目,然后小批量频繁的集成,控制分支就是说可以做到工作隔离,但是又不会增加太多的管理成本。小批量频繁的集成可以加速你的信息的同步。这里的分支数目,并不是说只能有一个 feature 分支,我们说的是分支类型的一个数目。所以这里我们给到了一个简单就是说你要从最大化生产力和最小化风险的这一个角度来去思考。

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

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

相关文章
|
5月前
|
C语言
(保姆级)一篇搞懂分支语句
(保姆级)一篇搞懂分支语句
93 6
|
3月前
|
项目管理 开发工具 Android开发
三类代码协同模式问题之开发者将远程上游仓库克隆到本地,并在本地创建开发分支问题如何解决
三类代码协同模式问题之开发者将远程上游仓库克隆到本地,并在本地创建开发分支问题如何解决
|
2月前
|
存储 前端开发 数据可视化
超详细图解说明:一个代码仓库如何管理多个项目、且代码提交互不影响。orphan分支的使用
这篇文章详细图解了如何使用Git的`--orphan`参数创建孤立分支来管理代码仓库中的多个项目,确保不同项目的代码提交互不影响,并提供了解决实际使用中可能遇到的问题的方法。
超详细图解说明:一个代码仓库如何管理多个项目、且代码提交互不影响。orphan分支的使用
|
3月前
|
Java 开发工具 git
代码协同模式使用问题之AGit-Flow协同模式是如何解决分支评审模式中特性分支过多、混乱的问题的
代码协同模式使用问题之AGit-Flow协同模式是如何解决分支评审模式中特性分支过多、混乱的问题的
|
3月前
|
存储 开发工具 Android开发
代码协同模式使用问题之创建特性分支,如何解决
代码协同模式使用问题之创建特性分支,如何解决
|
3月前
|
存储 数据库
领域模式问题之模型设计存在问题如何解决
领域模式问题之模型设计存在问题如何解决
|
2月前
|
存储 测试技术 持续交付
利于集成的分支策略
利于集成的分支策略
43 0
|
3月前
|
测试技术 程序员
W模型和瀑布模型与“V”模式开发模型有何异同?
W模型和瀑布模型与“V”模式开发模型有何异同?
|
4月前
|
C#
详细解读C#系列五《多样化的程序分支》
详细解读C#系列五《多样化的程序分支》
16 0
|
人工智能 数据可视化 数据挖掘
你只管提需求,大模型解决问题:图表处理神器SheetCopilot上线
你只管提需求,大模型解决问题:图表处理神器SheetCopilot上线
251 0