如何撤销有问题的git合并提交

20

我的一个同事不小心做了一次合并,结果只保留了树的一侧。他开始一次合并,然后删除了合并引入的所有更改,最后提交了该合并。

这是我在测试仓库上做的一个简单测试用例。该仓库有三个分支。 idx 是意外合并的主题分支,master 是主线。dev 只是一个 revert -m 如何工作的测试,所以您可以忽略它。

alt text

我想要做的是还原错误的合并。所以从主线 master 中,我尝试运行 git revert -m 1 <错误合并的 SHA1 校验和>,但 git 响应说:

# On branch master                               
nothing to commit (working directory clean)

所以它实际上并没有创建一个撤销合并的提交,我认为这是因为合并实际上并没有包含任何真正的更改。

这是一个git的bug,还是我漏掉了什么?


我不确定你为什么说“它实际上并没有创建合并提交” - 它本不应该。您应该期望它创建一个普通提交,以撤消合并提交的影响。 - Cascabel
是的,抱歉,那应该是说它实际上并没有创建还原提交。 - Jason Axelson
测试仓库链接已损坏,重定向到可疑网站。 - Tanvir
@Tanvir 谢谢,已经删除了旧的损坏链接。 - Jason Axelson
我不理解-m 1参数。为什么是1?还有哪些可能的值?如果是-m 2会发生什么? - Fábio Roberto Teodoro
2个回答

10

关于回退合并操作,git文档中有这样的说明:git/Documentation/howto/revert-a-faulty-merge.txt,其中主要是介绍如何回退引入错误更改的合并操作,而不是回退错误执行的合并操作。

基本上,回退一个合并操作将撤消数据更改,但不会撤销历史记录(图形)更改。因此,期望回退错误的合并操作不会产生任何效果。

您可以通过重新执行合并操作,然后将其结果合并到主分支中来解决此类问题。在您的示例中,可以采用以下方式:

git checkout -b temp/merge-fixup ead364653b601f48159bca5cb59d6a204a426168
git merge 2fce9bfe8f721c45ea1ed5f93176322cac60a1d9
git checkout master
git merge temp/merge-fixup
git branch -d temp/merge-fixup

2
现在似乎文档已经消失了。 - kojiro
1
@kojiro:今天谷歌搜索“revert-a-faulty-merge.txt”可以得到很多镜像。 - Frerich Raabe

9

最好的经验法则是在向公众发布你的 repo 后,绝对不要更改其历史记录。这会导致很多问题。虽然我认为这个案例无法避免这种情况。

我认为这里有几个选项,但最简单的是进行变基。使用你的 repo,以下是我使用的命令:

git rebase -i ead3646

然后,当交互式shell出现时,删除有问题的提交的整行。保存并应该得到像这样的新历史记录

* f0ab6d5 more normal work on dev
* ebb5103 idx commit
* ead3646 master change
* 582c38c dev commits
* f4b8bc6 initial commit

让你们(以及其他人)重新协调需要进行一些分支、推送、电子邮件和买午餐的操作。


重新同步并不那么复杂。虽然我从未在其他地方看到过食谱,但我写了一份并在此发布:https://dev59.com/D2855IYBdhLWcg3w6IzV - Aristotle Pagaltzis
2
我还没有仔细阅读关于合并提交的git revert文档,但-m选项是专门允许它在合并提交上操作的。显然应该有一种方法来实现它,问题是为什么在这种情况下它没有起作用。 - Cascabel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接