Git。恢复早于 HEAD 的提交失败

Git. Reverting a commit older than HEAD fails

我正在努力学习 git revert 命令。我正在尝试还原早于 HEAD 的提交。这是不允许的吗?

$ git touch sonic
$ echo sonic >> sonic
$ git add .
$ git commit -m "sonic"
$ echo the >> sonic
$ git add .
$ git commit -m "the"
$ echo hedgehog >> sonic
$ git add .
$ git commit -m "hedgehog"
$ git log --oneline
d65e56d (HEAD -> master) hedgehog
e37fefc the
c745775 sonic

然后

$ git revert HEAD^
Auto-merging sonic
CONFLICT (content): Merge conflict in sonic
error: could not revert e37fefc... the
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

我可以做 git revert HEAD,那会恢复 d65e56d 但不会 git revert HEAD^。这是不允许的吗? git revert HEAD^^ 也不行。

那不是失败。这也不算成功。这是一个 冲突 ,告诉你 Git 无法解决反向应用的问题。

发生冲突是因为您触碰了相邻的行。 firstsecond 版本之间的区别是 "add the word the at the end of the file, after the word sonic"。要撤消该操作,Git 需要删除文件 末尾 单词 sonic 之后的单词 the — 但文件没有到此为止。现在它继续包含单词 hedgehog

实际上,Git 不知道是删除最后一行 (hedgehog) 还是包含单词 the 的行。1 您可能认为这是显而易见的,但 Git 只是不知道如何。因此它因合并冲突而停止,并且在 indexstaging areathree 版本的文件可供您使用=59=],加上工作树中的 第四 版本,用冲突标记标记。现在您的工作是生成冲突文件的正确版本。

有很多方法可以做到这一点。我倾向于使用的方法是在我的编辑器中打开工作树文件,查找 <<<<<<< 行,然后观察这些行以找出正确的内容。 (我还将 merge.conflictStyle 设置为 diff3 以便我在冲突区域中得到一个额外的部分,向我展示文件的 base 版本中的内容就像两个冲突版本中的一样。不过在这种情况下它并没有真正帮助。)

将文件的工作树副本编辑到 "right answer"——不管那是什么——我把它写出来并退出我的编辑器,然后 运行 git add冲突的文件。冲突现在已经解决了,使用我放入的内容,不管之前是什么。

如果那是最后一次冲突(在本例中就是这样),git revert --continue 将恢复还原并继续您要求还原的任何其他提交(如果有)。由于没有更多的事情要做,这样就完成了恢复,你就大功告成了。


1从技术上讲,Git 试图合并两个更改,而不只是删除一个更改。两个之一说 删除 the,另一个说 添加 hedgehog。两者都在文件末尾,Git 无法找出正确答案。


恢复失败 HEAD^^ 类似,但这次 Git 的行是删除 the 与 Git 看到添加 sonic。如果不同的线之间有足够的间隙,问题就会消失。