





















事情的背景是,本人在开发中本地 feature 分支,git commit 了一个改动,commitid = 11111
然后执行 git merge origin master 到本地,生成了一个 MR commitid = 22222 此时:有 20+个文件修改合并到了 feature 分支
再执行了一波 git push origin feature 推送到远端。
此时,觉得好像修改整体有点问题,于是脑抽地执行了 git revert -m 1 22222 ( merge commit )
手动调整了一个 A 文件,再次 git commit ( commitid = 33333 ) 然后重新执行了 git push origin feature
于是我去 MR 到 master 了,此时按惯例检查 change list 并没有发现异常,MR 提示只有我修改的这个文件 A ,我便将这个文件 MR 到了 master 。
事情看起来好像没有什么不对,我以为回退了问题代码,并且 MR 检查 diff 也没问题,但是过了几天线上出问题了。。。有人陆续找我说自己 master 的代码“消失了”
检查了下,发现 checkout 到 master ,这 20+个文件的修改被“回退”了,而且 master 分支上有一个单独的 commit 记录:
Revert "Merge remote-tracking branch 'origin' into feature"
This reverts commit 22222, reversing
changes made to 33333.
紧急一顿通知恢复处理,评估影响+道歉。
事后回顾了下,有个比较大的疑点:为什么最后一次 MR 时,diff 里并没有提示 20+ 个文件实际发生了改动,而只 diff 出我 revert 后的这个文件 A 的改动,导致我没有及时发现 diff 有问题。
AI 分析了一波,结论大概是:
MR 合并时,Git 使用的是 三方合并( 3-way merge )
master: A --- B --- C
\ \
feature: M --- R --- .proto fix
合并时 Git 的逻辑是:
base:master 和 feature 的共同祖先
master:没变
feature:有 revert commit ( R )
👉 Git 看到的是:
“feature 分支主动撤销了这些改动”
于是合并结果就是:
✅ 这些改动在 master 上也被撤销了
也就是说:
feature 的 revert ,通过 MR 把 master 的内容给“反删了”
为什么 MR diff 里“看起来没事”?
原因是:
MR diff 是 最新状态对比
feature 上的 revert ,对 Git 来说:
✅ 不是“删除文件”
✅ 而是“对齐 master 并取消 merge 引入的差异”
这是 revert merge commit 最隐蔽、最危险的地方
看完分析,我依然觉得 git 这样设计很不合理。。。MR 不应该整体按照 feature 和 master 分支的最终 diff 来 MR 么?
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。