git merge丢失commit踩坑记
一、问题
最近项目中使用git merge时遇到特性分支上部分commit内容丢失(没有合并到main分支)。本文记录一下踩坑过程。
项目git分支管理采用了main、prod-x、feat-x 三类分支(不是标准的git flow分支管理)。feat分支是特性开发分支,开发前从main分支拉取;prod分支类似产品发布分支,也是所有特性分支的合并分支。prod分支每个版本计划完成后从main分支拉取,发布前把feat特性分支合并到prod分支,联测验证没有问题后再合并到main分支发布。
一般feat特性分支合并到prod合并分支时需要走gitlab代码Merge Request流程。
发生问题的场景是一次gitlab上提代码Merge Request时错误把目的分支选择了main(应该是prod分支),评审通过并合并到了main分支。
意识到问题后我们在gitlab上点了回滚,实际就是在main分支上进行代码回滚。
到这里一切似乎一切正常。
问题发生在prod分支合并到master分支时,feat分支之前开发的内容不能合并到main分支了(git merge成功但是commit丢失)。
二、原因分析
上面git分支提交过程可以通过mermaid gitGraph图表示如下。

在main分支git merge prod-0.1分支时,公共提交是F1-任务1,因为main分支和prod分支都合并过feat分支内容,虽然main分支回滚了。
prod-0.1合并到main分支时,从公共提交F1 - 任务1开始,后面git commit记录包括M1 - 代码合并、M2 - 错误合并从feat到main、C2-撤销M2的提交。可以看出最后一步的C2-撤销M2的提交会把F1 - 任务1提交回滚掉。
也可以这么理解:Git 会认为 “feat(即 F1) 的改动已经存在于 main(虽然被回滚)”,所以 M3 时不会重新引入 F1 的内容。
三、解决方法
解决方法是要修改合并分支的公共commit id。推荐方法如下:
- 重新从main分支拉一个feat-t1.1分支
- 把feat-t1分支上的
F1 - 任务1通过git cherry-pick提取到feat-t1.1 - 合并feat-t1.1到prod-0.1
- 合并prod-0.1到main分支
这样F1 - 任务1中的提交内容就能合并到main分支了。
四、参考
mermaid编程式画图挺不错,文中git画图指令参考如下
1 | gitGraph |
可以通过支持mermaid的markdown平台插件来编辑和渲染,也可以简单通过在线平台https://mermaid.live/编辑和导出。