如何在git中撤销上一个提交,但保留我的更改为未暂存状态?

43

我已经提交了更改,但现在很难看出我都做了哪些修改。当然我可以使用git diff,但我宁愿撤销上次提交并保留所有更改,这样我的IDE(PyCharm)只会显示哪些文件已被更改。

那么有没有一种方法可以撤销上次提交(真正删除它),但仍然保留我的更改?欢迎提供所有提示!


3
小细节:你实际上从 Git 历史记录中并不会真正“删除”提交。相反,你会删除指向它们的指针(即分支)。最终它们将被垃圾回收。如果你搞砸了什么并想要回去,你可以在 reflog 中找到这些悬空提交。 - Drew Noakes
我还建议熟悉JetBrains(PyCharm等)IDE中内置的git浏览器,因为它们会显示您在特定提交中所做的更改,而无需“取消提交”您的更改。如果您刚刚提交了某些内容,这个解决方案可能有效,但是想象一下,如果您需要回到上个月提交的内容,会发生什么! - blueberry_chopsticks
3个回答

38

我建议在其他两种答案中去掉 --soft 参数,使用简单的命令 git reset @^(或旧版本的 git reset HEAD^),这会默认为 git reset --mixed @^。不同之处在于软重置会保留文件暂存区,这似乎不是您想要的结果。如果您真的想撤销提交,您还应该取消暂存的更改,这是默认操作。在一般情况下,我发现这比软重置更有用,这可能是为什么混合重置是默认值的原因。


1
这应该是被接受的答案——更简单,正好符合OP的要求。 - chetstone
有人能解释一下上面答案中的 @^ 吗?我在 Windows 上这样做,但 GitBash 会问我 more?,不知道是什么意思。 - Post Impatica
1
没事了,找到答案了:在Windows中,^是一个转义字符,所以你必须使用两个。否则,gitbash会问你“更多?”。所以:git reset @^^ - Post Impatica
2
@PostImpatica使用2个“^”字符让我感到害怕,因为“^”字符会堆叠,所以“@^^”看起来像是引用了2个提交。听起来“^^”在Windows中会被解析成单个“^”,但我可能仍然会养成在该环境中使用“@1”的习惯,这相当于正常的非Windows“^”,只是为了避免混淆自己。如果你想回到三个,“@3”更明显地表示了3个回退,而不是“@^^^^^^”! - Gary Fixler

30
根据Peter的说法,我会选择`git reset --soft`,这样可以保留你的索引和工作目录的完整性。
在你的情况下,如果你想回退1个提交,你可以使用`git reset --soft HEAD~`将分支指向当前HEAD的父提交;你的索引和工作目录仍将包含你修改过的文件。
关于reset的一篇有用的文章:http://git-scm.com/blog/2011/07/11/reset.html

3
天啊,伙计,你一个人解决了这个问题,这应该是被接受和最受赞的答案。如果不加上 HEAD~git reset --soft 的末尾,什么也没发生。 - Harry
很高兴能帮到你 =D - Chris

20

这听起来像是使用 git reset --soft 的工作,该命令的帮助文档(git help reset)中有这样的说明:

--soft
    Does not touch the index file nor the working tree at all
    (but resets the head to <commit>, just like all modes do).
    This leaves all your changed files "Changes to be
    committed", as git status would put it.

因此,提交被撤消了,但文件看起来仍然与之前相同。没有将任何内容暂存到索引中。


我刚刚运行了 git reset --soft,但是当我运行 git hist 时,我仍然看到我的最后一次提交。所以我猜这不是解决我的问题的办法。还有其他的想法吗? - kramer65
2
提交仍然存在于历史记录中,但是HEAD不再指向它。这是一个悬空引用,并将被垃圾回收。 - Peter Westlake
8
作为一个提示;最终我通过执行 git reset --soft <上一个提交的哈希值> 成功了。插入哈希值最终解决了我的问题。无论如何还是谢谢! - kramer65

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