如何用Git流(Git Flow)管理release和hotfix分支?

文章导读
用Git Flow管理release和hotfix,最要紧的不是记住命令,而是搞清楚分支的起点和终点。release分支负责把开发中的代码冻结成发布版,hotfix分支负责在线上出问题时补一个紧急修复。下面按照我平时检查的顺序,记一下每个环节怎么判断、怎么操作,以及在哪里最容易翻车。
📋 目录
  1. 先判断是否该开 release
  2. release 分支的改动边界
  3. hotfix 该从哪里拉
  4. 合并后做什么检查
  5. 合并时容易漏掉的步骤
A A

用Git Flow管理release和hotfix,最要紧的不是记住命令,而是搞清楚分支的起点和终点。release分支负责把开发中的代码冻结成发布版,hotfix分支负责在线上出问题时补一个紧急修复。下面按照我平时检查的顺序,记一下每个环节怎么判断、怎么操作,以及在哪里最容易翻车。

先判断是否该开 release

在某些团队里,release分支开得比功能分支还随意,代码没测完就拉出来,最后发布计划被拖得很难看。我一般会先检查两个条件:功能列表是否全部合入develop,测试环境是否具备验收条件。只有这两点满足,才建议从develop分出release分支。

在Git Flow中,release分支的创建时机通常以功能开发完成且develop分支达到可发布状态为标志。如果团队采用语义化版本,那么从develop分出release分支时,版本号应当从当前开发版本切换到即将发布的正式版本,例如从1.2.0-SNAPSHOT切换到1.2.0。判断是否需要创建release分支,可以检查功能列表是否已全部合入develop,以及测试环境是否已具备验收条件。若仍有未完成的高优先级功能,则不应创建release分支,而应继续在develop上合并。

补充一点:release分支创建后,develop并不需要冻结,新功能可以继续往develop上合,但要注意这些新功能不要通过任何意外合并溜进release。如果团队接下来还要发多个小版本,release分支的命名可以带上版本号,例如release/1.2.0,方便后续打标签和回溯。如果团队还没有统一版本号策略,可以先定一个简单的规则,否则从SNAPSHOT切换正式版本时,容易漏改某个配置文件。

如何用Git流(Git Flow)管理release和hotfix分支?

release 分支的改动边界

release分支的目的是收口,不是重新开发。创建release分支后,只允许进行bug修复、文档更新和版本号调整,禁止合并新的功能特性。所有修复应当先合入release分支,再通过合并release到develop和master来同步变更。建议在release分支上完成回归测试后,将release合入master并打上版本标签,同时将release合入develop以反向合并修复内容。这样既能锁定发布内容,又能避免develop因缺少修复而落后。

这里的“反向合并”容易被忽略,尤其当团队多人并行时,release分支上修的bug如果不回develop,后面的新功能分支就会带着旧bug继续走。建议每次release合并后,先切到develop执行git pull,确认没有冲突,再继续开发。如果release分支上发现需要新功能,不要顺手在这个分支上写,正确做法是让新功能留在develop,等下一个发布周期;实在要救,就废弃当前release分支,从develop重新拉一条。

hotfix 该从哪里拉

线上问题通常很急,但越急越要确认分支起点。hotfix分支必须从master或对应的release标签拉取,而不是从develop拉取。因为hotfix需要基于当前线上的实际代码修复问题,develop上可能包含尚未发布的功能,混入这些功能会扩大发布范围,增加回归风险。hotfix完成后应同时合并到master和develop,但合并顺序有讲究:先合并到master并打补丁版本标签,再合并到develop,以免develop的版本号被覆盖。如果多个hotfix并发,最好按顺序逐个处理,合并后立即更新下游分支。

实际执行时,hotfix分支命名可以像hotfix/1.2.1这种,明确对应要打的补丁版本。如果线上版本和release分支同时存在,建议先处理release分支的合并,再处理hotfix,或者至少让hotfix基于最新master拉取,避免在develop上产生交叉冲突。如果线上问题涉及数据库迁移,hotfix里可以带迁移脚本,但脚本内容要和master上的schema保持一致,不能把develop上的模型结构一起带过去。

如何用Git流(Git Flow)管理release和hotfix分支?

合并后做什么检查

合并动作不是推一下就结束。我通常在执行合并前先看一遍待发布提交,命令如下:

git log --oneline master..release

逐条比对release分支上的提交,确认没有误合入未计划的功能。确认版本号也已经被改成正式版本,再执行合并和打标签。打完标签后,再执行git tag -l,确认标签名称和提交位置都正确。

hotfix合并到master后,标签同样要打清楚,比如v1.2.1。这里有个容易出错的地方:如果先从release分支合并到develop,develop版本号可能还停在下次开发的快照版本,此时再合并hotfix,会把develop的版本号覆盖成补丁版本。所以顺序和标签检查一样都不能少。检查版本号时,可以直接看package.json或pom.xml,但更稳妥的是用git diff master..release -- pom.xml来比较,确认只差预期的那几个值。如果项目用的是Node,就把路径换成package.json。

如何用Git流(Git Flow)管理release和hotfix分支?

合并时容易漏掉的步骤

按我的观察,hotfix合并回develop这个步骤最容易被遗忘。线上问题修复后,master和发布版本都有补丁,但develop没有,结果下一次从develop开的功能分支还是带着同一个bug,回头还要再修一遍。建议在hotfix合并完后,立刻切到develop执行合并,中间不要让develop被其他分支推进太多。

另一个细节是版本号同步。release分支或hotfix分支上调整版本号后,要确保develop拿到的版本号是下一个开发版本,而不是刚刚发布的版本。如果发现版本号冲突,先做一次本地比较,再决定哪边保留。分支多的时候,用git log --graph --all看一遍分支拓扑,基本能看出合流方向和重复标签。另外,打标签时建议带上注释,比如git tag -a v1.2.1 -m 'hotfix for issue xxx',方便之后查当时为什么补这个版本。

整个Git Flow分支管理,关键不在于工具,而在于每个分支的起点和终点是否明确。release和hotfix是对发布和修复的两条保护线,保留它们的独立性,后面排查问题时才不会一头雾水。