如何恢复倒数第二次提交而不是最后一次提交?

时间:2017-01-11 20:42:14

标签: git

假设我有四次提交A-->B-->C-->D,但C非常误导。如何在不丢失D变化的情况下撤消C?我理解git-revertundoing commits的基本功能,但我无法弄清楚如何(如果可能的话)撤消特定提交(不是最新的)而不必重做那些更改来之后。

2 个答案:

答案 0 :(得分:9)

还原

git revert命令旨在完成此操作。

git revert <hash for C>

这将创建一个新的提交,它会反转C中的更改。

重写历史

您还可以重写历史记录。这通常不建议使用,只有在您有充分理由从历史记录中实际删除提交时才应使用(例如,如果它包含密码或其他内容)。

git rebase -i <hash for B>

在编辑器中,只需删除带有C的哈希的行。如果你已经推动,通常需要注意。

非交互式

从技术上讲,所有这些选项都涉及某种合并解决方案,这意味着它们不能真正是非交互式的。唯一的区别是由此产生的历史。使用git revert,您会看到如下所示的历史记录:

A -> B -> C -> D -> E
                    ^
                    +--- reverts C

使用git rebase,您最终得到的结果如下:

A -> B -----------> E

您当然可以git rebase --onto B C代替git rebase -i,但这仍然是一个交互式流程,因为您必须手动解决任何无法解决的合并冲突通过合并策略自动解决。

答案 1 :(得分:2)

假设:

  • A,B,C和D是提交哈希值(在遇到它们的地方用哈希替换它们)
  • 您实际上希望提交C从历史记录永久地从主分支中删除,而不是由“恢复”提交掩盖。如果不是这种情况,请使用git revert C

一般步骤

  • 在提交B处创建一个新的分支(此分支应该看起来像A-> B)
  • Cherry将提交D选择到新分支。 (它应该是A->B->D')它会得到一个新的哈希值,我称之为D'
  • 切换到主分支
  • 删除C&amp; D从主分支提交(main将看起来像A->B - 合并你的新分支 进入主要(主要应该是A->B->D'
  • 删除测试分支。

以下是代码:

git checkout -b temp B
git cherry-pick D   
git checkout master
git reset --hard HEAD^^
git merge temp
git branch -D temp