你如何恢复错误的 git 合并提交

Posted

技术标签:

【中文标题】你如何恢复错误的 git 合并提交【英文标题】:How do you revert a faulty git merge commit 【发布时间】:2011-05-04 07:07:54 【问题描述】:

所以我的一位同事不小心做了一个合并,实际上只保留了树的一侧。于是他开始了一次合并,删除了合并引入的所有变更,然后提交了合并。

这是我在测试存储库中所做的一个简单测试用例。这个 repo 有三个分支。 idx是不小心合并的topic分支,master是主线。 dev 只是测试 revert -m 的工作原理,所以你可以忽略它。

我想要做的是恢复错误的合并。所以从主人那里我尝试运行git revert -m 1 <sha1sum of faulty merge>,但随后 git 回应:

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

因此它实际上并没有创建撤消合并的还原提交。我相信这是因为合并实际上并没有包含任何真正的变化。

这是一个 git 错误,还是我遗漏了什么?

【问题讨论】:

我不确定你为什么说“它实际上并没有创建合并提交”——它不应该。您应该期望它会创建一个正常的提交,这会逆转合并提交的效果。 是的,很抱歉应该说它实际上并没有创建一个还原提交。 测试回购链接已损坏,重定向到一个阴暗的网站 @Tanvir 谢谢,删除了旧链接。 【参考方案1】:

git 文档中关于还原合并的说明:git/Documentation/howto/revert-a-faulty-merge.txt 虽然这主要是关于恢复带来错误更改的合并,而不是恢复错误完成的合并。

基本上,还原合并将撤消数据更改,但不会撤消历史记录(图表)更改。因此,预计恢复错误的合并不会有任何作用。

您可以解决此问题的一种方法是再次进行合并,然后将结果合并到 master 中。在您的示例中,这可能是这样的:

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

【讨论】:

现在文档似乎不见了。 @kojiro:到今天为止,谷歌搜索revert-a-faulty-merge.txt 会产生大量镜像。【参考方案2】:

这里最好的经验法则是在你的回购公开后永远不要改变它的历史。这真的把事情搞砸了。不过,我认为这种情况无法避免。

我认为这里有几个选项,但最简单的是做一个 rebase。使用您的存储库,这些是我使用的命令:

git rebase -i ead3646

然后,当交互式 shell 出现时,删除错误提交的整行。保存它,您应该拥有一个新的历史记录,如下所示:

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

让你们两个(和其他人)重新同步需要一些分支、推送、电子邮件和午餐购买。

【讨论】:

恢复同步真的没那么复杂。不过,由于我从未在其他地方看到过食谱,所以我写了一个并将其发布在此处:***.com/questions/4084868 我没有机会仔细阅读关于合并提交主题的git revert 文档,但-m 选项专门允许它对合并提交进行操作。显然应该有办法做到这一点,问题是为什么它在这种情况下不起作用。

以上是关于你如何恢复错误的 git 合并提交的主要内容,如果未能解决你的问题,请参考以下文章

Git 恢复未提交的更改

我如何恢复 `git fetch 上游; git 合并上游/master`? [复制]

在 Git 中,如何恢复在提交之前还原的暂存文件?

非线性合并后如何恢复线性git历史?

重新提交在 git 中恢复的提交

你如何恢复到 Git 中的特定标签?