Skip to content
文章目录

gitflow 使用

gitflow 约定的分支

  • master 分支,始终最后稳定版本内容的分支,由 release 分支合并养成。 固定,一直保持当前最新稳定的发布版本代码,在 CI/CD 建设时,你可以只在该分支做签名、公证等一系列自动化流程
  • develop 分支,所有新功能开发的基础、开发阶段冒烟修复问题等。 固定,这是我们日常的开发分支,所有新功能分支都将合并到该分支
  • feature/* 分支,一切功能开发的子分支,基于 develop,完成后合并到 develop
  • bugfix/* 分支,用于修复缺陷的分支名前缀。可删,这种分支一般情况下基于 develop 或者 release/* 分支开出,作为简单的缺陷修复分支,最终合并到 developrelease/* 分支中
  • release/* 分支,保存每一个版本的迭代信息,由 develop 分支生成。可删,进入预发布阶段时基于 develop 创建的分支,再此基础集成,它名字可能是 release/2.8.0,release/2.9.0 等。
  • hotfix/* 分支,用于线上版本紧急修复的分支. 可删,是对线上最新版本或长期服务版本做紧急修复时使用的分支,他不是常驻的
  • support/* 分支,一般用于特殊功能支持的分支(不合并到主分支)

通过 git flow 工具链创建的分支,如 git flow hotfix start 1.0.1 会以固定格式进行命名,这样可以清晰的告诉我们哪些分支起源于哪里、用于做什么、终结于哪里。gitlab 中查看到的分支结构也会变得非常清爽。下图是 gitflow 的工作流的示例图:

gitflow 使用命令

shell
# 开始和完成一个功能
git flow feature start "功能名"
git flow feature finish

# 开始和完成一个版本的发布
git flow release start "release版本"
git flow release finish

# 开始和完成一个 hotfix
git flow hotfix start "hotfix版本"
git flow hotfix finish

gitflow 命令解读

git flow feature start user-mgr 新建一个 feature 分支

新建一个user-mgrfeature分支. 分支名feature/user-mgr

对应如下git命令

shell
# 当前在 develop 分支
git branch -b feature/user-mgr

git flow feature finish

feature/user-mgr 分支会自动合并到 develop 分支,并且将自动删除临时的 feature 分支。

对应如下git命令

shell
# 完成功能
git checkout develop
git merge --no-ff feature/user-mgr
git branch -d feature/user-mgr

如果您对主仓库的 develop 有推送权限,那么可以直接推送代码到仓库中,但某些场景下,团队是需要 code review 的,您可以将 feature/* 分支推送到你 fork 的子仓库中,并以 Pull RequestMerge Request 的方式提交到主仓库的 develop 分支进行 code review。当然 code review 的方式有很多种,我们可以根据自己团队的需求来做一些改变。

git flow release 让版本发布自动化

当进入一个发布窗口期,我们需要考量一下哪些功能可以在准备发布的版本进行发布了,这些功能首先会被合并到 develop 分支,这里避免不了会有一些代码的冲突,需要指定功能的负责人进行合并,在确认无误后我们开启一个准备发布的分支:

shell
git flow release start 8.0.0

执行以上命令后,我们就基于 develop 分支开启了一个 release/8.0.0 的分支,你可以使用该分支做整体预发布功能的回归、做一些版本号修改、文档更正等简单的工作。这个分支不在进行大规模的代码调整,仅做一些回归时发现的小缺陷修复,这个周期通常要 1~2 天的时间。当确认该分支代码稳定可以发布时,执行如下命令进行发布:

shell
# 当前在 release/8.0.0 分支
git flow release finish

该命令执行了如下几个操作:

  • 合并 release/8.0.0master 分支
  • 创建 8.0.0 tag
  • 合并 8.0.0 tagdevelop 分支

整个 release 版本发布的阶段,转化为 git 的原生指令他是这样一个步骤:

shell
# 当前工作与 develop 分支
git checkout -b release/8.0.0

# 做一些简单修复或者版本更改,提交代码
git commit -a -s -m "Update version..."

# 完成版本发布
git checkout master
git merge --no-ff release/8.0.0
git tag -a 8.0.0
git checkout develop
git merge --no-ff 8.0.0
git branch -d release/8.0.0

整个发布过程的指令就是这些,看似简单,但是当我们自己操作时很难不出错误,特别是版本发布和线上缺陷(hotfix)修复同时进行的时候,如果有这些辅助指令可以大大加快我们的工作效率且不容易出错。在 release 阶段你可以让你的自动构建系统配合 git-flow 的固有规则进行构建,比如我们可以根据分支名称或者当前最新 tag 自动给产出物做版本号的修改,而不需要我们在代码中新建一个提交去修改这些内容。

另外我更建议在 release/* 分支做版本发布,而不是 master 分支,master 分支仅作为一个备份分支,他在一些开源项目中显得比较重要,因为他代表着最新稳定分支。但公司内部的一些开发团队中来看 master 分支可有、可无。但是你不能在 master 分支随便产生一个提交,这样会打乱 git flow 的工作流程,你要来来回回合并好几次才能保证各个协作分支正常工作。之所以建议在 release/* 分支做发布操作,是因为有些时候在你执行完 git flow release finish 后还会发现有一些非常简单的错误需要修复,比如对外文档中的一个符号错误、一个错别字、甚至版本号错误等,这些都是避免不了的。如果你已经合并到 master 分支,你需要基于 develop 重来一遍发布流程,这会产生非常多的麻烦。何不在 release 分支就都完成了呢?当产品上线、部署到官网后,下一个迭代开始前,在执行 git flow release finish 更好。

git flow hotfix 线上缺陷紧急修复

谁都不愿意看到线上出现紧急问题,出问题不要怕,解决它并告诉自己不要再犯同样的错误,这也是我为什么使用 git flow 一个很重要的原因。以往的线上紧急问题修复中,我们通常是基于 master 或者最新 tag 拉取一个分支,在这个分支中做缺陷的紧急修复,分支名称比较随意,有时带版本、有时不带版本,不同人的做法不一导致这个流程出现很多问题。在紧急问题修复后我们要把这些修复的问题合并回 master,但同时我们需要将这个修复合并到我们正在开发或者准备发布的分支中,这一步是经常容易忘记的,无论你是新来的同事还是老同学都可能在这里犯错。

而使用 git-flow 则可以非常简单的避免这些问题,它有非常完善的 hotfix 流程,确保你在修复问题时不影响常规迭代,当线上发生紧急问题时,你需要基于 master 分支执行如下命令:

shell
git flow hotfix start 8.0.1

该命令会基于 master 创建一个 hotfix/8.0.1 的分支,在进行一系列缺陷修复并通过测试后,使用如下命令完成这个紧急修复:

shell
git flow hotfix finish

git-flow 命令行工具会自动根据当前分支获取要使用的版本号,它将执行如下功能:

  • 将修复合并到 master 分支确保主干为最新得到修复的内容
  • 新建 8.0.1tag
  • 将修复同时合并到 develop 分支,确保当前开发分支也同样得到修复而不是被遗忘
  • 删除临时的 hotfix 分支

两条命令帮助我们做了非常多我们容易忘记的事情,同时版本号的管理也更加严禁不会轻易让我们出错,自动根据版本号创建 tag 也让我们的紧急修复可以被追溯。上面简单的两条命令还原为 git 的原生命令是如下代码:

shell
# 基于 master 开启分支
git checkout -b hotfix/8.0.1

# 修复内容
git commit -a -s -m "Fixed something"

# 合并修复到主干和开发分支
git checkout master
git merge --no-ff hotfix/8.0.1
git tag -a 8.0.1
git checkout develop
git merge --no-ff 8.0.1 # merge tag
git branch -d hotfix/8.0.1

机器代码最容易解决的就是流程上的问题,但最难解决的是变更。当你在准备下一个 release 版本比如 release/8.1.0 时,此时线上又出现了紧急的缺陷待修复必须马上发版本解决。团队决定又不准备做版本回滚,那么就要有一些变更了。我们需要在完成修复代码后将修复内容合并到 release/8.1.0 分支,而不是 develop 分支,因为在 release/8.1.0 完成后会自动合并到 develop,确保我们的代码不会被丢失。这些场景我们的确有碰到。但我更建议在流程上避免这些事情,release 分支的新建代表下一个迭代版本即将发布,如不是非常紧急的问题可以等待新版本发布,否则可能对现有发布流程产生影响。

git flow support 长期服务分支维护

私有化版本在我们的团队中是“家常便饭”,这些私有化版本常常无法与主版本代码保持一致,包括 hotfix 也无法覆盖到这些版本中。通常的情况是我们最新的版本已经发布到 8.0.0 版本,但外部还有使用 7.4.07.9.0 版本的客户,他们因为业务稳定性的要求,很难升级 SDK 至最新版本,你不得不把一些主版本已经修复的问题单独合并到这些长期维护分支中,它很像 LinuxLTS 版本。

git-flow 模型中,使用 support/ 前缀来管理这些长期维护版本分支,当我们确定某个版本的代码是需要长期维护的,并且客户在这个版本中提到了一些已知问题,我们需要对这些问题进行修复时,首先基于该版本开启一个 support 分支。如下:

shell
git flow support start 7.4.x 7.4.0

以上命令是基于 7.4.0tag 开启了一个新的分支 support/7.4.x 分支,这个分支就长期存在了,你不能删除它,它的级别与 master、develop 是一样重要的,比 release、hotfix 等更重要。因为他保存了这个长期支持分支的所有修复内容。接下来我们基于这个长期服务分支进行问题修复:

shell
git flow hotfix start 7.4.1 support/7.4.x

此命令代表我们要基于 support/7.4.x 分支开启一个 hotfix 修复,修复后的版本号我们定在 7.4.1。在新的 hotfix 分支上我们进行问题代码修复,修复完成后执行

shell
git flow hotfix finsih '7.4.1'

执行此命令后会有如下几个操作:

  • 合并 hotfix/7.4.1support/7.4.x 分支
  • 新建 tag 7.4.1
  • 删除 hotifx/7.4.1 的分支

这样基于 support/7.4.x 分支开启的所有修复都会合并回该分支中,它一直保持最新。在团队协作过程中,hotfix/* 分支开启后,需要在该分支中提测和测试,在确保无误后再合并到 support/* 分支确保。

我们来总结一下 git flow support 拆分成单独的 git 原生指令是如何工作的:

shell
# 新建分支
git checkout 7.4.0
git branch -b support/7.4.x

# 基于 support/7.4.x 新建 hotfix
git checkout -b hotfix/7.4.1

# 解决问题并合并修复
git commit -a -s -m "fix: somthing"
git checkout support/7.4.x
git merge --no-ff hotfix/7.4.1
git tag 7.4.1
git branch -D hotfix/7.4.1

参考文章

基于 git flow + gitlab 协作开发:01

基于 git flow + gitlab 协作开发:02 解决问题