Git 撤消推送合并并删除其历史记录

Git undo pushed merge and delete its history

我不小心合并到 master 并推送了它,现在 master 拥有来自 dev 的所有提交。我想在不更改 dev 的情况下还原 master 的提交并删除其历史记录。我该怎么做?

您可以使用 reflog 找出合并前 master 指向的位置,并使用 reset 命令将其重置为该位置。提交不会被删除,因为仍然在 dev 中,但 master 不会有它们。如果你真的想删除那些,即同时重置开发,你可以这样做,孤儿提交最终将被垃圾收集。

这里有一个例子,但不要只是将其用作食谱,而是阅读更多有关 Git 以及 Git 的工作原理(git 结构)的内容并在其他地方练习(其他分支机构/其他回购),当你有信心回到这个并尝试。

Recovering lost commits

可以删除最后一次提交:git reset --hard HEAD^

有时可能会出现这样的情况,当您需要从分支的 "middle" 中删除提交时。救援交互式 rebase 来了:git rebase -i <commit>^。您只需要删除不需要的提交(它应该出现在列表的顶部)。

如果您撤消的更改在远程可用,则它们也应该通过强制推送从那里删除:git push --force

但是,重写已与某人共享的分支的历史记录并不是撤消更改的好方法。相反,请考虑使用 git revert <commit>。在这种情况下,这是更稳健和正确的方法。

我建议阅读 Git Branching - Rebasing。第 "The Perils of Rebase" 章解释了为什么重写 public 历史不是一个好主意。

$ git revert -m 1 <merge-commit-hash>
  1. git revert 将确保创建一个新的提交来恢复不需要的合并的影响。这与 git reset 相反,我们有效地从历史记录中“删除”提交。这也是为什么在您已经推送到远程的情况下,git 恢复是更好的解决方案的原因。

  2. -m 1 选项告诉Git我们要保留合并的父端(这是我们合并到的分支)。

  3. 最后,还要确保提供正确的提交哈希:对于上面的 git 重置示例,我们必须在合并之前提供提交;但是,当使用 git 还原时,我们必须指定实际合并提交的哈希值。

https://www.git-tower.com/learn/git/faq/undo-git-merge/