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 模型中有两个永久存在的分支:masterdevelop

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 &amp;&amp; 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的工作模式,剩下的命令你都可以举一反三,灵活应用,更多信息请查看官方文档。