【问题标题】:Git: how to revert a branch merge without overwriting history?Git:如何在不覆盖历史记录的情况下恢复分支合并?
【发布时间】:2011-07-20 00:17:49
【问题描述】:

我有两个分支:masteropengl。我最近完成了opengl 分支的实现(或者至少我是这么认为的),并决定将其合并到master

git checkout master
git merge opengl
git push

在我这样做之后,几个在 master 分支上工作的开发人员撤回了我的更改,结果发现我的实现与他们的一些代码冲突。因此,我想恢复 master 分支上的合并操作,但不覆盖历史记录。

请注意,我希望最终能够将opengl 分支合并到master 中(在我修复所有错误之后)。因此,只需检查旧版本的 master 并提交它是行不通的 - 当我尝试合并它时,新创建的提交将取消我对 opengl 的更改。

谢谢。

【问题讨论】:

标签: git merge branch revert


【解决方案1】:

cebewee 提到的文档“How to revert a faulty merge”解释了为什么 git revert 在恢复合并时很棘手。

所以合并仍将存在,它仍将被视为将两个分支连接在一起,并且未来的合并会将合并视为最后一个共享状态 - 以及恢复合并的恢复引入根本不会影响这一点。
如果您将“还原”视为“撤消”,那么您将永远错过这部分还原。
是的,它会撤消数据,但不,它不会撤消历史记录。

git revert 在这里是正确的解决方案,但是当您想再次合并该分支时,它会在将来产生影响。
然后下一次合并必须先“revert the revert”,然后再合并分支。

【讨论】:

  • 我想强调最后两个短语,因为它们非常重要(而且很容易错过,然后不明白不恢复 revert 提交的后果。)
  • 另见git-scm.com/blog/2010/03/02/undoing-merges.html,它有一个“Reverting the Revert”部分
【解决方案2】:

编辑:事实证明 不是 是 OP 要求的,但我会保留它,以防有人碰巧寻找解决方案 确实涉及改写历史。


首先,如果您想在本地保留合并提交,请创建一个新分支,以便在您移动 master 后提交不会“消失”:

git branch erroneousMerge master

如果其他开发人员在错误合并后也进行了提交,他们也必须这样做!

然后,重置master 以引用合并前的最后一次提交;假设它是提交e498b2...:

git checkout e498b2
git branch -f master

现在,您可以推送更正后的master-f 表示您想让服务器将其master 分支重置为您指向的提交,即使此提交是它在存储库中指向的那个):

git push -f origin master

现在,其他开发人员可以更新他们的master 以匹配服务器(-f 表示他们接受分支已向后移动):

git fetch -f origin master:master

如果其他开发者在错误合并后进行了更改(假设合并提交是abc123,他们可以使用rebase将更改移动到更正后的master

git rebase --onto master abc123 oldMaster

如果您在某个时候搞砸了并以“丢失”提交而告终,因为不再有任何分支指向它们,您可以使用 git fsck --lost-found 来恢复它们。

【讨论】:

  • 您的建议完全是覆盖历史记录。我想避免这种情况,因为使用存储库的人太多,而且所有人都必须执行此操作。我相信有更好的方法。
  • 您可以创建一个新的提交,使用git revert(也在@cebewee 发布的链接中描述)来反转合并提交的效果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-28
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 2021-03-11
  • 1970-01-01
相关资源
最近更新 更多