一、背景引入
在最近的一次版本发布过程中,我们遇到了一个典型的Git操作问题。当时,我们有一个高危代码修复需要同步到60、62、63等多个版本分支。同事的做法是:基于60创建hotfix分支,然后在62、63分支上分别拉取hotfix分支,再分别执行cherry-pick操作将修复提交复制过去。表面上看,代码同步成功了,各分支都包含了修复。
但重点问题在于:当后续需要追溯这个修复影响了哪些tag版本时,执行git tag --contains <commit-hash>(哈希码是低版本的代码提交记录值)却只能找到60分支的tag,62、63分支的tag完全没有被包含进来。
为什么会这样?
- 因为相同的代码改动,在不同分支上通过cherry-pick产生了完全不同的commit hash值。
二、问题复现场景
常用命令准备
# 查看包含commit的tag
git tag --contains <commitId>
# 标签
# 创建本地标签
git tag <tag-name>
# 推送单个标签
git push origin <tag-name>
# 删除本地标签
git tag -d <tag-name>
# 删除远程标签
git push origin --delete <tag-name>
本地快速复现问题
cherrypick方式实现多版本分支修复(复现问题)
首先我们准备两个release分支,一个release_1.1.x、一个release_1.2.x。
首先我们基于release_1.1.x创建一个分支hotfix_1.1.x_tt1,并进行一次代码提交:

当前的哈希码为:96d60ae7
接着我们来对release_1.2.x分支来进行创建一个分支hotfix_1.2.x_tt2,然后从hotfix_1.1.x中的提交记录给cherry pick过来:

当前的哈希码为:eae3f452
接着我们分别在hotfix_1.1.x_tt1中创建一个tag叫做v1.1.1:
git tag v1.1.1
然后切换到hotfix_1.2.x_tt2中也创建一个tag叫做v1.2.1:
git tag v1.2.1
接下来,我们使用一开始hotfix_1.1.x_tt1的哈希码来进行搜索下:
git tag --contains 96d60ae7

你可以发现搜索同一份代码相关的tag只能够搜索到v1.1.1。
merge方式实现多版本分支修复
首先我们准备两个release分支,一个release_1.1.x、一个release_1.2.x。
首先我们基于release_1.1.x创建一个分支hotfix_1.1.x_tt1,并进行一次代码提交:

当前的哈希码为:96d60ae7
接着我们来对release_1.2.x分支来进行创建一个分支hotfix_1.2.x_tt2,然后将hotfix_1.1.x_tt1代码来进行合并过来:

此时的提交记录为:

接着我们分别在hotfix_1.1.x_tt1中创建一个tag叫做v1.1.1:
git tag v1.1.1
然后切换到hotfix_1.2.x_tt2中也创建一个tag叫做v1.2.1:
git tag v1.2.1
接下来,我们使用一开始hotfix_1.1.x_tt1的哈希码来进行搜索下:
git tag --contains 96d60ae7

至此你就能够搜到原始1.1.x版本涉及到代码的所有tag了,后续我们就可以直接进行删包处理即可,能够精准定位所有的tag包。
三、知识点补齐
核心概念:Cherry-pick vs Merge的本质区别
在使用Git进行跨分支代码同步时,我们需要理解两种操作的本质区别:
| 操作方式 | commit关系 | 追溯能力 | 适用场景 |
|---|---|---|---|
| Cherry-pick | 产生新commit,与原commit无关联 | ❌ 无法通过原commit追溯 | 临时修复、一次性同步 |
| Merge | 保留commit关联关系 | ✅ 可通过原commit追溯 | 长期跟踪、高危修复 |
重点:cherry-pick是复制代码改动,但切断历史关联;merge是合并分支,保留完整的提交父子关系。

四、Cherry-pick & merge使用场景
何时使用Cherry-pick,其适用场景是:
- 临时热更新:线上紧急问题,需要快速发布,不考虑长期追溯
- 单次代码同步:只需要这次同步,后续不会再有关联修改
- 实验性功能:不确定是否会合并回主线的功能验证
注意:使用cherry-pick时,一定要意识到它切断了历史关联,对于修改的代码就是一次新的提交记录,哈希值就会变。
何时必须使用Merge:
- 高危代码修复:需要完整追溯影响范围的修复
- 安全补丁:涉及安全漏洞的修复,必须能准确定位所有受影响版本
- 长期维护分支:需要持续同步修复的分支
- 版本发布追溯:后续可能需要删包、回滚的操作
评论区请在客户端页面查看