3.3.1 Git分支管理
代码管理经历了集中式源代码管理到分布式源代码管理的演变过程。集中式的版本控制系统以Subversion为代表,版本库集中存放于中央服务器。分布式的版本控制系统以Git为代表,版本库存在于每个开发人员的电脑上,因而不再需要中央服务器,提交代码时也不再需要进行网络连接。后者已经成为代码管理的事实标准,可应对团队协同合作可能出现的各类问题。
分支管理是Git代码管理的核心。合理的分支管理可以帮助我们高效协同开发。那么,常见的Git分支管理策略有哪些呢?又该如何选择呢?
1.Git工作流
Vincent Driessen在其2010年发表的题为“A successful Git branching model”的博文中提出了一种基于Git的分支管理策略,在相当长的一段时间内成了Git分支管理的事实标准,我们称该标准为Git工作流(Git Flow)。Git工作流定义了五种分支类型。
● 主干分支(master):Git自动创建的分支。代码有且只有一个主干分支,任何正式版本的发布都应基于主干分支。
● 开发分支(develop):用来存放日常开发代码的稳定版本。开发分支与主干分支都是长期存在的分支。
● 功能分支(feature):开发人员开发特定功能的分支。功能分支应当从开发分支中拉出,并在开发完成后合并回开发分支。
● 预发布分支(release):正式版本发布之前用来做预发布的分支,应当与预发布环境配合。每次产品预发布时,应当从开发分支拉出预发布分支用于打包和部署,等到正式发布时,再将预发布分支合并回开发分支与主干分支。与功能分支不同,预发布分支应当有固定的命令规则,一般用release-*表示。*表示正式版本的下一个版本号,如release-3.1.1。
● 补丁分支(hotfix):从主干分支而非开发分支中拉出的分区。补丁分支用来修复生产环境的缺陷,因而是按需创建的,也没有固定的版本号,正式发布后需要被合并回开发分支和主干分支。合并完成后删除补丁分支。
Git工作流的工作流程如图3-6所示。
我们可以将五种分支分为两类,长期分支和短期分支。其中主干分支和开发分支是长期分支,功能分支、预发布分支和补丁分支是短期分支。开发人员日常使用的分支主要是短期分支。下面我们将介绍三种短期分支的使用方式。
(1)功能分支
首先,使用如下命令创建功能分支。
然后,在开发完成后将其向开发分支中合并。
最后,使用如下命令删除功能分支。
图3-6
(2)预发布分支
首先,使用如下命令创建预发布分支。
然后,在正式版本发布后,将预发布分支合并回主干分支和开发分支,并打好标签。
最后,在合并完成后使用如下命令删除预发布分支。
(3)补丁分支
首先,使用如下命令创建补丁分支。
然后,在正式版发布后,将补丁分支合并回主干分支和开发分支,并打好标签。
最后,在合并完成后使用如下命令删除补丁分支。
Git工作流有着诸多优点,例如分支命名语义明确、支持预发布环境、支持多版本的生产环境等。这些优点或多或少影响了后续的各种Git分支管理流程。
2.GitHub工作流
GitHub工作流(GitHub Flow)作为一种轻量级分支管理策略被广泛使用,它的一些主要特点如下。
● 任何时候主干分支都是可发布的。
● 开发时从主干分支拉出新分支,但不区分功能分支和补丁分支。
● 开发完成后将新分支推到远端。
● 通过向主干分支提出合并请求(Pull Request,以下简称PR)通知团队其他成员进行评审和讨论。
● PR被接受后,代码将被合并进主干分支,并触发持续部署。
GitHub工作流的优势在于足够简单,因此受到开源社区的欢迎。但是很多时候,代码合并进主干分支并不意味着可以立即发布。比如很多企业会有固定的上线窗口,只有在特定的时间可以发布新版本,这会导致线上版本远远落后于主干分支。
此外,GitLab团队在2014提出了GitLab工作流(GitLab Flow)。它和GitHub工作流最大的不同是加入了环境分支,比如预发布分支和生产分支。
3.单一工作流
Adam Ruka在其2015年撰写的GitFlow considered harmful一文中提出了一种新的分支管理策略,即单一工作流(One Flow)。单一工作流可以看作Git工作流的替代品,主要区别是,单一工作流不再维护两个长期分支,而使用主干分支来替代Git工作流中的开发分支。因此,功能分支和预发布分支都拉取自主干分支,而补丁分支拉取自预发布分支。与Git工作流相比,单一工作流的代码更干净,更容易读懂,维护成本更低。此外,阿里巴巴也提出了类似的分支管理策略——Aone工作流,核心思想同样是将主干分支和开发分支合并成一个分支。
在实际的项目开发中,我们团队同时使用了多种分支管理策略:采用Git工作流来发布前台应用,既能满足多环境、多版本的管理需求,又能保证应用的质量;采用单一工作流来发布微服务应用,规避掉Git工作流的繁文缛节;采用GitHub工作流来管理内部工具。读者可以根据团队的实际情况选择合适的分支管理策略。