Git-flow作者称其不适用于持续交付?
前言
Git-flow
是由Vincent Driessen
在2010年提出的一个Git
分支模型,在这10年中,Git-flow
在许多软件团队中变得非常流行,以至于人们开始将其视为某种标准。
不过最近Vincent Driessen
更新了他10年前那篇著名的A successful Git branching model,大意是Git-flow
已不适用于当今持续交付的软件工程方式,推荐更简单的Github flow
等模型
连Git-flow
作者都承认Git-flow
不适合持续交付了,那我们更有必要好好研究一下了,以免掉坑里。
本文主要包括以下内容:
1.Git-flow
介绍
2.为什么Git-flow
不适用于持续交付?
3.Github flow
介绍
4.Gitlab flow
介绍
1. Git-flow
是什么?
Git-flow
是由Vincent Driessen
在2010年提出的一个Git
分支模型,其结构图如下所示,相信大家都看过Git-flow
主要包括以下分支
master
是长期分支,一般用于管理对外发布版本,每个commit
对一个tag
,也就是一个发布版本develop
是长期分支,一般用于作为日常开发汇总,即开发版的代码feature
是短期分支,一般用于一个新功能的开发hotfix
是短期分支 ,一般用于正式发布以后,出现bug
,需要创建一个分支,进行bug
修补。release
是短期分支,一般用于发布正式版本之前(即合并到master
分支之前),需要对预发布的版本进行测试。release
分支在经历测试之后,测试确认验收,将会被合并到develop
和master
1.1 Git-flow
工作流程
一般工作流程如下:
- 1.日常在
develop
开发 - 2.如果有比较大的功能或者其他需求,那么新开分支:
feature/xxx
来做,并在这个分支上进行打包和提测。 - 3.在封版日,将该版本上线的需求合并到
develop
,然后将开个新的分支release/版本号
(如release/1.0.1
),将develop
合并至该分支。 - 4.灰度阶段,在
releases/版本号
分支上修复BUG,打包并发布,发布完成后反合入master
与develop
分支 - 5.如果在全量发布后,发现有线上问题,那么在对应的
master
分支上新开分支hotfix/{版本号}
来修复,并升级版本号,修复完成后,然后将hotfix
合并到master
,同时将合并到develop
2. 为什么Git-flow
不适用于持续交付?
在这 10 年中,
Git
本身已经席卷全球,并且使用Git
开发的最受欢迎的软件类型正在更多地转向Web
应用程序——至少在我的过滤器气泡中。Web
应用程序通常是持续交付的,而不是回滚的,而且您不必支持同时 运行的多个版本的软件。
如Vincent Driessen
所述。Git-flow
描述了feature
分支、release
分支、master
或develop
分支以及hotfix
分支是如何相互关联的。
这种方法非常适用于用户下载的打包软件,例如库和桌面应用程序。
然而,对于许多Web
应用来说,Git-flow
是矫枉过正的。有时,您的develop
分支和release
分支之间没有足够大的差异来区分值得。或者,您的hotfix
分支和feature
分支的工作流程可能相同。
在这种情况下,Vincent Driessen
推荐Github flow
分支模型
Git-flow
的主要优点在于结构清晰,每个分支的任务划分的很清楚,而它的缺点自然就是有些复杂了Git-flow
需要同时维护两个长期分支。大多数工具都将master
当作默认分支,可是开发是在develop
分支进行的,这导致经常要切换分支,非常烦人。
更大问题在于,这个模式是基于"版本发布"的,目标是一段时间以后产出一个新版本。但是,很多网站项目是"持续发布",代码一有变动,就部署一次。这时,master
分支和develop
分支的差别不大,没必要维护两个长期分支
2.1 Git-fow
何时值得额外的复杂性
当然,是否使用Git-flow
取决于你的业务复杂性,有时使用Git-flow
是必须的,主要是当你需要同时维护多版本的时候,适合的是需要『多个版本并存』的场景
所谓『多版本并存』,就是说开发团队要同时维护多个有客户使用的版本,对于传统软件,比如我开发一个新的操作系统叫做Doors
,先卖v1
,卖出去1000万份,然后看在v1
的基础上开发v2
,但是客户会持续给v1
提bug
,这些bug
既要在v1
的后续补丁中fix
,也要在v2
中fix
,等v2
再卖出去2000万份开始开发v3
的时候,v1
依然有客户,我就必须要维持v1
、v2
、v3
三个多版本都要支持。
关于Git-flow
同时支持多个版本,很多人可能会有疑问,因为develop
只针对一个版本能持续交付
说实话我也感觉挺疑问的,后面查阅资料发现还有一个衍生的support
分支,可以同时支持多个版本,在兴趣的同学可参考:mindsers.blog/post/severa…
3.Github flow
介绍
Github flow
它只有一个长期分支,就是master
,因此用起来非常简单。
- 第一步:根据需求,从
master
拉出新分支,不区分功能分支或补丁分支。 - 第二步:新分支开发完成后,或者需要讨论的时候,就向
master
发起一个pull request
(简称PR
)。 - 第三步:
Pull Request
既是一个通知,让别人注意到你的请求,又是一种对话机制,大家一起评审和讨论你的代码。对话过程中,你还可以不断提交代码 - 第四步:布署流程:当项目负责人同意新功能可以发布,且代码也通过审核了。但是在代码合并之前还是要进行测试。所以要把
feature
分支的代码部署到测试环境进行测试 - 第五步:你的
Pull Request
被接受,合并进master
,重新部署到生产环境后,原来你拉出来的那个分支就被删除。 - 第六步:修复正式环境
bug
流程:从master
分支切一个HotFix
分支,经过以上同样的流程发起PR
合并即可
3.1 Github flow
的优点
Github flow
的最大优点就是简单,对于"持续发布"的产品,可以说是最合适的流程。
3.2 Github flow
的缺点
它的问题也在于它的假设:master
分支的更新与产品的发布是一致的。也就是说,master
分支的最新代码,默认就是当前的线上代码。
可是,有些时候并非如此,代码合并进入master
分支,并不代表它就能立刻发布。比如,苹果商店的APP
提交审核以后,等一段时间才能上架。这时,如果还有新的代码提交,master
分支就会与刚发布的版本不一致。另一个例子是,有些公司有发布窗口,只有指定时间才能发布,这也会导致线上版本落后于master
分支。
上面这种情况,只有master
一个主分支就不够用了。通常,你不得不在master
分支以外,另外新建一个production
分支跟踪线上版本。
同时对于Github flow
我还有个疑问,合并到master
分支后即会部署到生产环境,但是在merge
后的代码难道不会产生冲突吗?合并冲突难道不需要重新测试吗?如果评论区有了解的小伙伴可以解惑下
Github flow
用起来比较简单,但是在很多公司的业务开发过程中一般都有开发、测试、预发布、生产几个环境,没有强有力的工具来支撑,我认为很难用这种简单的模式来实现管理。
看起来这种模式特别适合小团队,人少,需求少,比较容易通过这种方式管理分支。
4.Gitlab flow
介绍
Gitlab flow
是 Git-flow
与Github flow
的综合。它吸取了两者的优点,既有适应不同开发环境的弹性,又有单一主分支的简单和便利。它是Gitlab.com
推荐的做法。Gitlab flow
的最大原则叫做”上游优先”(upsteam first
),即只存在一个主分支master
,它是所有其他分支的”上游”。只有上游分支采纳的代码变化,才能应用到其他分支。Gitlab flow
分为持续发布与版本发布两种情况,以适应不同的发布类型
4.1 持续发布
对于”持续发布”的项目,它建议在master
分支以外,再建立不同的环境分支。
比如,”开发环境”的分支是master
,”预发环境”的分支是pre-production
,”生产环境”的分支是production
。
开发分支是预发分支的"上游",预发分支又是生产分支的"上游"。代码的变化,必须由"上游"向"下游"发展。比如,生产环境出现了bug
,这时就要新建一个功能分支,先把它合并到master
,确认没有问题,再cherry-pick
到pre-production
,这一步也没有问题,才进入production
。
只有紧急情况,才允许跳过上游,直接合并到下游分支。
4.2 版本发布
对于"版本发布"的项目,建议的做法是每一个稳定版本,都要从master
分支拉出一个分支,比如2-3-stable
、2-4-stable
等等。
以后,只有修补bug
,才允许将代码合并到这些分支,并且此时要更新小版本号。
4.3 Gitlab flow
开发流程
对于Android
开发,我们一般使用版本发布,因此我们使用Gitlab flow
开发的工作流为
- 1.新的迭代开始,所有开发人员从主干
master
拉个人分支开发特性, 分支命名规范feature-name
- 2.开发完成后,在迭代结束前,合入
master
分支 - 3.
master
分支合并后,自动cicd
到dev
环境 - 4.开发自测通过后,从
master
拉取要发布的分支,release-$version
,将这个分支部署到测试环境进行测试 - 5.测出的
bug
,通过从release-$versio
拉出分支进行修复,修复完成后,再合入release-$versio
- 6.正式发布版本,如果上线后,又有
bug
,根据5的方式处理 - 7.等发布版本稳定后,将
release-$versio
反合入主干master
分支
值得注意的是,按照Github flow
规范,第5步如果测出bug
,应该在master
上修改,然后cherry-pick
到releases
上来,但是这样做太麻烦了,直接在releases
分支上修复bug
然后再反合入master
分支应该是一个简单而且可以接受的做法
总结
正如Vincent Driessen
所说的,总而言之,请永远记住,灵丹妙药并不存在。考虑你自己的背景。不要讨厌。自己决定。
Git-flow
适用于大团队多版本并存迭代的开发流程Github-flow
适用于中小型团队持续集成的开发流程Gitlab-flow
适用范围则介于上面二者之间,支持持续发布与版本发布两种情况
总得来说,各种Git
工作流自有其适合工作的场景,毕竟软件工程中没有银弹,读者可根据自己的项目情况对比选择使用,自己决定~
参考资料
如何看待 Git flow 发明人称其不适用于持续交付?
Git 开发工作流程:Git Flow 与 GitHub Flow
Git 工作流程
高效团队的gitlab flow最佳实践