TL;DR Git Flow是一种得到广泛认可的模型,通过确定分支的实际用途(master/develop/feature等),达到团队共同认知认可全部开发过程效果。
为什么需要Git开发规范(模型)
随着Git的普及,几乎所有的开发团队都在使用Git进行版本管理和团队协作。但是Git本身提供的功能很多,灵活性太大,每个人都可以有自己的使用方式和代码管理风格。
混乱的开发流程
如果整个团队没有一个共同的Git使用共识,那么合作起来需要沟通和作出妥协,沟通不畅的情况下还可能导致的问题。
轻则,分支名字千奇百怪:有的用日期,有的用功能名称,有的用Bug编号,有的用开发者自己的名字,甚至是混合体;本地分支和远程分支几十个,谁也不知道具体的分支是做什么的。
严重的情况则比如:
A向master提交了未经测试的下一个迭代或者版本才会上线的代码,并push到了服务器,这个时候线上代码出现问题需要紧急修复,B负责此事,他没有和A沟通,认为master上的代码就是线上代码,直接pull下来,修复了bug所在的代码片段,并将代码发布到了线上,这个时候A提交的未经测试的代码出现在了线上,同时由于未经过测试所以出现了很严重的Bug导致系统不可用。
这种情况在团队人员水平参差不齐或者来自不同的小组,缺乏良好沟通和合作经验的情况下,很有可能会出现。
常见的Git规范
针对这种情况,这个团队需要一个全员都认可并知晓的Git代码管理规范,这种规范最好是经过长时间工程实践考验的,通用的,容易学习和灵活的。目前工程领域里有两个开发规范或者说开发模型符合这些特征:一个是开源项目比较通用的同时也是Github官方推荐的Pull Request的方式,另一个是今天我们将要重点说明的Git Flow模型。
Git Flow简介
Git Flow模型源自Vincent Driessen在2010年发布的一篇文章: A successful Git branching model, 这边文章得到了很多人的认同(比如阮一峰的Git分支管理策略)并且在工业界得到了广泛的应用。
两个永久分支
Git Flow 模型中有两个永久存在的分支:master
和 develop
master分支
master分支上的代码永远代表着当前生产环境的代码状况,并且master分支只接受代码合并,不接受commit提交
develop分支
develop分支的代码代表这下一个迭代将要发布的代码情况,没有确定下来将要在下一个迭代发布的代码不能合并在这个分支。devlop分支的代码和master分支同步或者领先master分支,绝对不会出现落后master分支的情况。
若干辅助分支
feature分支
业务的需求等都可以看作是产品的特性,feature分支就是正在开发的多个特性构成的集合,feature分支可以同时拥有多个,具备统一的命名规范(具体命名规范在下文中详述)。feature分支起源于develop分支,最终也将合并至develop分支,但也有例外:试验性的特性如果最终证明是失败的,将被删除而不合并入develop。每一个feature代表着一个特性,这些特性只在开发完毕准备下个迭代发布时合并入develop分支,不在下一个迭代发布的特性不能合并到develop分支。
hotfix分支
线上代码出现严重Bug需要紧急修复时使用该分支。hotfix分支起源于master分支(也就是线上代码),开发完成后合并至master分支同时合并到develop分支以确保下一个版本的代码也包含这个hotfix补丁。
release分支
当develop分支代码测试完毕,准备发布时,将从develop分支发起release分支,进入release阶段的代码将不允许新特性的添加(也就是不允许feature分支合并入develop分支或者release分支),又称特性冻结(feature freeze)。release分支将进行最终最严格的测试。release分支接受为了修复bug而产生的提交。release分支持续变动,直至开发工作验收通过,这时release分支将会打上版本标签(tag)合并至master分支同时合并至devlop分支以确保develop分支是master分支的直接后继。
bugfix分支
bugfix分支和hotfix分支目的类似,但bug紧急程度不需要立即修复,而是留到下一个版本发布时修正。和hotfix不同的是bugfix起源于develop分支也最终合并于develop分支,这一点和feature分支非常相似。
support分支
如果项目有老版本的代码因为各种原因需要维护时,会需要support分支来管理这些过时但是依旧需要维护的代码。
special分支
对应于软件的各种特别版本:节日特别版(圣诞等),周年特别版等
Git Flow AVH 介绍
除了这些标准规范,作者还提供了Git的插件帮助开发者更快和更好的处理具体的细节,我们现在介绍的是比较流行的Git Flow AVH版本。
安装
这里使用Linux下安装为例子,更加详细和更多平台的安装指南请查阅官方维基git-flow AVH Edition
安装开发版本:
wget --no-check-certificate -q https://raw.githubusercontent.com/petervanderdoes/gitflow-avh/develop/contrib/gitflow-installer.sh && sudo bash gitflow-installer.sh install develop; rm gitflow-installer.sh
`</pre>
安装稳定版本:
<pre>`wget --no-check-certificate -q https://raw.githubusercontent.com/petervanderdoes/gitflow-avh/develop/contrib/gitflow-installer.sh && sudo bash gitflow-installer.sh install stable; rm gitflow-installer.sh
初始化
Git flow 通过让你回答一些分支命名规则等信息来初始化。 大体问题如下:
- 默认的生产发布分支(production releases)的名字是什么【默认是master】
- 默认的develop(“next release” development)分支的名字是什么【默认是develop】
- 默认的feature分支的前缀是什么【默认是feature/】
- 默认的bugfix分支的前缀是什么【默认是bugfix/】
- 默认的release分支的前缀是什么【默认是release/】
- 默认的hotfix分支的前缀是什么【默认是hotfix/】
- 默认是support分支的前缀是什么【默认是support/】
- 默认的版本号的前缀是什么【默认是是空】
- Git flow的hooks和filters的路径 [默认是git项目中的.git/hooks目录]
通过这些问题,Git flow获取了相关的配置设定,初始化完成
通用模式
Git flow的命令存在一个通用的模式,亦即 git flow MODE ACTION NAME [BASE]
, 下面将一一介绍:
MODE
MODE亦即模式,表示你想要使用的git flow的功能,功能负责映射命令到分支和相应的动作,常见模式有
- feature
- bugfix
- hotfix
- release
ACTION
ACTION亦即动作,表示你想要在这个模式下执行的动作,常见的动作模式有
- start
- finish
NAME
NAME亦即名字,表示你要完成的对象的名字,这个部分完全由你自己定义,有下面几个建议
- feature / bugfix 模式下使用英文描述命名,因为这个可以方便的了解这些分支的用途
- hotfix / release 模式使用版本号命名
[BASE]
按照传统惯例,[]内包裹的部分是可选的,这也不例外,base仅在start动作才有,finish动作并无此参数,base表示的是你想要操作的对象不是以默认的分支作为起点,而是以base参数指定的commit id作为起点
使用范例
开始新的feature
假设你想要开始一个新的feature,这个feature对应产品需求的“增加回复功能“,你可以使用命令如:git flow feature start add_replay_function
, 该命令将会执行如下动作:
- 基于develop分支(或者你在初始化时指定的develop对应的分支)创建 ‘feature/add_replay_function’分支(如果你在初始化时改变了默认的feature/的分支前缀,这里也会发生相应的变动)
- 切换到刚刚新建的分支
在命令中feature
是MODE,start
是ACTION,add_replay_function
是NAME
完成新的feature
当你完成一个feature的开发时,你可以使用命令:git flow feature finish add_replay_function
,该命令将会执行如下操作:
- 将分支’feature/add_replay_function’(名字可能有所不同,见"开始新的feature"部分,下同)合并到develop分支
- 将本地的’feature/add_replay_function’分支删除
- 切换到develop分支
在命令中feature
是MODE,finish
是ACTION,add_replay_function
是NAME
开始release
当一切准备就绪,准备开始发布新版1.0的时候,你可以使用命令如:git flow release start 1.0
, 该命令将会执行如下动作:
- 基于 develop 分支创建 release/1.0 分支
- 切换至 release/1.0 分支
在命令中release
是MODE,start
是ACTION,1.0
是NAME,注意这里的名字实际时版本号,这里推荐使用版本号
完成release
当发布完成之后,使用命令:git flow release finish 1.0
, 该命令将会执行如下动作:
- 合并 release/1.0 到 master
- master分支被打上tag
- 合并 release/1.0 到 develop
- 删除本地的 release/1.0 分支
- 切换至 develop 分支
中间可能会要求你填写的信息:
- 要求你填写 release/1.0 合并到 master 的 merge message,有默认值,可以直接使用默认值
- 要求你填写 tag 信息,这次提交将会被打上tag,没有默认值,建议填写本次发布的内容,改变等信息
- 可能会让你填写 release/1.0 合并到 develop 的 merge message,有默认值,可以直接使用默认值
通过以上的例子,你应该已经理解git flow的工作模式,剩下的命令你都可以举一反三,灵活应用,更多信息请查看官方文档。