如何在Git中返回到之前的提交版本而不丢失最新的提交?

21

我想做的是回到之前的两个提交,将在该提交中更改的文件作为一个新的提交带回来。但是,我不想失去我的最后一个提交。我的最后一个提交有一些代码错误,但现在我想暂时保留它。

我阅读了一些文档,但没有哪一个清楚地说明当您重置头时会发生什么。例如,如果向后重置,您是否会失去直到要重置到的那个提交之前的所有提交?

我试图理解所有这些命令如何运行,但是对于Git中的revert,resetcheckout命令感到相当困惑。

我意识到我应该储藏(stash)最后一次提交而不是提交(commit),但那又是另一件事情了。


1
你能具体说明一下你想做什么吗?你是想撤销之前的提交吗?还是想保留这两个提交所做的大部分更改,只是对某些文件进行修改? - John Szakmeister
jszakmeister,我不想删除任何提交。我想保留我的过去历史记录。我只是想把之前的两个提交作为一个新的工作阶段带回来。 - yarun can
“bring back” 的意思仍不清楚。 - wRAR
我最近也遇到了类似的情况,我是这样解决的:在旧提交的下方创建一个新分支,就在你不想要的两个提交之下。切换到新分支,你将拥有恰好在两个不想要的提交之前的状态。你不想要的提交将安全地留在原来的分支上。你可以在新分支上继续工作,一旦你满意,你可以将旧分支合并或者精选到新分支中,反之亦然。 - Cerno
3个回答

20
如果您想返回到之前的第2个提交点,只需执行git checkout HEAD~2即可。这将使您返回到那时候的所有内容。如果您在master分支上,git checkout master将使您回到当前状态。但是,如果您想保留当前状态但在那里开始新的开发分支,git checkout -b HEAD~2将在那里启动一个新分支。如果您想重置主分支但不想丢失当前未完成/损坏的工作,请执行:
git branch wip           # New branch ends a current tip
git reset --hard HEAD~2  # Old branch rewound, get files from then

13

revert命令会创建一个新的提交,以撤销旧提交所做的更改。 reset --hard 命令会将当前分支的HEAD更改为指定的提交。 checkout 命令则将工作副本切换到指定的分支或提交。

当你将分支重置为旧提交时,如果这些较新的提交不属于其他分支或是标签的祖先,它们将会丢失(但通过使用reflog依然可以访问)。

目前还不清楚您需要做什么,最可能的解决方案是使用revert(完全还原一个旧提交或一系列提交)和rebase -i(更改一个旧提交或从历史记录中删除它)。


1
“git revert”有很强的含义,因为它创建了一个提交,来否定之前提交所做的更改。除非你确定自己的意图,否则在使用时要小心。 - Maic López Sáenz
@LopSae创建的提交尚未发布,因此如果它执行了您不想要的操作,您可以轻松删除它。相比之下,重置和变基是更危险的命令,因为从错误中恢复的难度更大。 - wRAR
嗨,@wRAR。当我回退到之前的提交时,在使用 git log 查看提交历史时,我切换回去的提交之后的所有记录都丢失了。如何解决?我的意思是在我回退到之前的提交后查看完整的提交历史。 - Mario
@Mario 如果你不记得需要的提交ID,可以尝试在git reflog中查找。 - wRAR

0

使用$ git reflog命令,您可以查看最后的哈希值,这对于在从先前提交强制推送后丢失最后提交时返回到先前状态非常有用。

另外:

$ git fsck --no-reflog
$ git show <hash>
$ git checkout -b <new-branch> <hash>

GL

源代码


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接