背景

在使用 ​​git flow​​ 流程时, 对于项目型的部署项目经常会遇到一个问题, 就是现场项目在使用历史版本时发现的一些问题需要修复, 但升级可能会有很大的风险或客户不愿意升级, 这时就要求基于历史版本进行 hotfix 修复.
基于历史发布版本的缺陷修复方式不同于最新发布版本的补丁修复方式, 因为历史版本的分支再合并到 master 上, 可能目录结构及文件存在特别大的差异, 导致冲突无法正常的合并.

基于最新发布版本的合并

一般大家都知道, 如果在 master 最新的 tag 上发现了需要修复的问题, 直接基于需要修复的 tag 拉取分支进行修复, 修改完成后把代码合并到 master 中发补丁版本, 并合并( merge )到目前的 develop 或 release 分支中.

git checkout 6.0
git checkout -b hotfix/6.0.1

在 hotfix_version 分支中修复完成后, 合并到 master 发布 tag.

git checkout master
git merge hotfix/6.0.1
git tag 6.0.1

合并修改到 develop 或 release (主要看目前在哪个阶段), 示例为 develop 阶段

git checkout develop
git merge hotfix/6.0.1
git branch -d hotfix/6.0.1

后续 develop 分支合并到 master 后, develop 和 master 的日志图像会引用到 hotfix , 显示会比较乱, 如下图所示

*    b66ca1b (tag: 2.0) Merge branch 'develop'        ==> master 合并 develop
|\
| |
| * df20397 develop update 2
| * d0ed525 develop update 1
| * 778bd03 Merge branch 'hotfix-1.0.1' into develop ==> 引用到 hotfix-1.0.1 的修改
| |\
| * | 26a23fd git develop add a file t1.txt
* | | cb413a9 Merge branch 'hotfix-1.0.1' ==> master 合并 hotfix-1.0.1, 引用到了 hotfix-1.0.1 修改
|\ \ \
| | |/
| |/|
| * | 959dfc5 (hotfix-1.0.1) hotfix 1.0.1 update 2
| * | ecc876d hotfix 1.0.1 update1
|/ /
* | 679c836 this is a hotfix for 1.0.1
|/
* a27b457 (tag: current, tag: 1.0) add three line
* 72e54f1 add two line
* 5418748 add one line

可以使用 ​​merge -squash​​ 压缩 hotfix 到 develop 的合并, 日志图像显示会比较清晰, 如下图所示:

*   51ae281 (HEAD -> master) Merge branch 'develop'
|\
| * 5532d53 (develop) Squashed commit of the following: ==> develop 通过 squash 合并 hotfix-3.0.1, 没有引用 hotfix-3.0.1 修改
| * e9942da this is a develop update 2
| * efc9829 this is a develop update 1
* | ec8d038 Merge branch 'hotfix-3.0.1' ==> master 合并 hotfix-3.0.1
|\ \
| * | ccae1bf (hotfix-3.0.1) this is a hotfix-3.0.1 update 1
| * | d00da78 this is a hotfix 4.0.1
|/ /
|/
*

至此, 整个流程完成.

基于历史发布版本的合并

但是, 如果修复的 tag 是历史的版本, 需要引入 support 长期分支, 作用跟 master 类似, 用于发布 tag 版本.

git checkout 6.0
git checkout -b support/6.x
git checkout -b hotfix/6.0.1

在 hotfix_version 分支中修复完成后, 合并到 support 中发布 tag.

git checkout support/6.x
git merge hotfix/6.0.1
git branch -d hotfix/6.0.1
git tag 6.0.1

如果使用了 gitflow 命令行工具, 可以简化为:

git flow support start 6.x 6.0
git flow hotfix start 6.0.1 support/6.x
# 问题修复后
git flow hotfix finish 6.0.1

但是把 hotfix 的修改不能直接合并到 master 中, 会引起特别大的冲突. 所以要先合并到最新 develop 或 release 中, 不建议直接通过无参的 merge 命令合并, 会存在较长的日志引用路径.
建议使用 ​​cherry-pick​​ 或 ​​merge -squash​​ 进行合并.

git checkout develop
# 单个合并
git cherry-pick commitid
# 或使用 squash 合并
git merge -squash hotfix/6.0.1