Git-flow作者称其不适用于持续交付?

6,001 阅读10分钟

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

前言

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 分支在经历测试之后,测试确认验收,将会被合并到 developmaster

1.1 Git-flow工作流程

一般工作流程如下:

  • 1.日常在develop开发
  • 2.如果有比较大的功能或者其他需求,那么新开分支:feature/xxx 来做,并在这个分支上进行打包和提测。
  • 3.在封版日,将该版本上线的需求合并到develop,然后将开个新的分支release/版本号(如release/1.0.1),将develop合并至该分支。
  • 4.灰度阶段,在releases/版本号 分支上修复BUG,打包并发布,发布完成后反合入masterdevelop分支
  • 5.如果在全量发布后,发现有线上问题,那么在对应的master分支上新开分支hotfix/{版本号}来修复,并升级版本号,修复完成后,然后将hotfix合并到master,同时将合并到develop

2. 为什么Git-flow不适用于持续交付?

在这 10 年中,Git 本身已经席卷全球,并且使用 Git 开发的最受欢迎的软件类型正在更多地转向 Web 应用程序——至少在我的过滤器气泡中。 Web 应用程序通常是持续交付的,而不是回滚的,而且您不必支持同时 运行的多个版本的软件。

Vincent Driessen所述。Git-flow描述了feature分支、release分支、masterdevelop分支以及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,但是客户会持续给v1bug,这些bug既要在v1的后续补丁中fix,也要在v2fix,等v2再卖出去2000万份开始开发v3的时候,v1依然有客户,我就必须要维持v1v2v3三个多版本都要支持。

关于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 flowGit-flowGithub flow的综合。它吸取了两者的优点,既有适应不同开发环境的弹性,又有单一主分支的简单和便利。它是Gitlab.com推荐的做法。
Gitlab flow的最大原则叫做”上游优先”(upsteam first),即只存在一个主分支master,它是所有其他分支的”上游”。只有上游分支采纳的代码变化,才能应用到其他分支。
Gitlab flow分为持续发布与版本发布两种情况,以适应不同的发布类型

4.1 持续发布


对于”持续发布”的项目,它建议在master分支以外,再建立不同的环境分支。
比如,”开发环境”的分支是master,”预发环境”的分支是pre-production,”生产环境”的分支是production

开发分支是预发分支的"上游",预发分支又是生产分支的"上游"。代码的变化,必须由"上游"向"下游"发展。比如,生产环境出现了bug,这时就要新建一个功能分支,先把它合并到master,确认没有问题,再cherry-pickpre-production,这一步也没有问题,才进入production

只有紧急情况,才允许跳过上游,直接合并到下游分支。

4.2 版本发布


对于"版本发布"的项目,建议的做法是每一个稳定版本,都要从master分支拉出一个分支,比如2-3-stable2-4-stable等等。
以后,只有修补bug,才允许将代码合并到这些分支,并且此时要更新小版本号。

4.3 Gitlab flow开发流程

对于Android开发,我们一般使用版本发布,因此我们使用Gitlab flow开发的工作流为

  • 1.新的迭代开始,所有开发人员从主干master拉个人分支开发特性, 分支命名规范 feature-name
  • 2.开发完成后,在迭代结束前,合入master分支
  • 3.master分支合并后,自动cicddev环境
  • 4.开发自测通过后,从master拉取要发布的分支,release-$version,将这个分支部署到测试环境进行测试
  • 5.测出的bug,通过从release-$versio拉出分支进行修复,修复完成后,再合入release-$versio
  • 6.正式发布版本,如果上线后,又有bug,根据5的方式处理
  • 7.等发布版本稳定后,将release-$versio反合入主干master分支

值得注意的是,按照Github flow规范,第5步如果测出bug,应该在master上修改,然后cherry-pickreleases上来,但是这样做太麻烦了,直接在releases分支上修复bug然后再反合入master分支应该是一个简单而且可以接受的做法

总结

正如Vincent Driessen所说的,总而言之,请永远记住,灵丹妙药并不存在。考虑你自己的背景。不要讨厌。自己决定

Git-flow适用于大团队多版本并存迭代的开发流程
Github-flow适用于中小型团队持续集成的开发流程
Gitlab-flow适用范围则介于上面二者之间,支持持续发布与版本发布两种情况

总得来说,各种Git工作流自有其适合工作的场景,毕竟软件工程中没有银弹,读者可根据自己的项目情况对比选择使用,自己决定~

参考资料

如何看待 Git flow 发明人称其不适用于持续交付?
Git 开发工作流程:Git Flow 与 GitHub Flow
Git 工作流程
高效团队的gitlab flow最佳实践

扩展阅读

一些大厂的Git工作流,有兴趣的同学可以了解下
在阿里,我们如何管理代码分支?
字节研发设施下的 Git 工作流
简介我的 Git Work Flow