如何取消本地git commit


743

我的问题是我更改了一个文件,例如:README,添加了新行“ this for my test line ”并保存了文件,然后发出了以下命令

 git status

 # On branch master
 # Changed but not updated:
 #   (use "git add <file>..." to update what will be committed)
 #   (use "git checkout -- <file>..." to discard changes in working directory)
 #
 #  modified:   README
 #
 no changes added to commit (use "git add" and/or "git commit -a")


 git add README

 git commit -a -m 'To add new line to readme'

我没有将代码推送到github,现在我想取消此提交。

为此,我用了

   git reset --hard HEAD~1

但是我从README文件中丢失了新添加的行“ this fortest line ”。这不应该发生。我需要那里的内容。有没有办法保留内容并取消我的本地提交?


3
听起来您绝对不是在要求git revert,它会使用已还原提交的反向差异创建一个新提交。重置只是将您当前的分支指向另一个提交,在这种情况下,就是您要“忘记”的提交之前的分支。
卡斯卡贝尔2011年

1
注意:可能值得一提的是,git-commit如果将消息保留为空白,则可能会中止,因此,如果您尚未真正完成提交,则可能会有所帮助。
GKFX

Answers:


1417

只使用git reset不带--hard标志的:

git reset HEAD~1

PS:在基于Unix的系统上,您可以使用HEAD^等于HEAD~1。在Windows HEAD^上将无法正常运行,因为^发出了连续行的信号。所以您的命令提示符只会问您More?


13
顺便说一下,这--mixed 在手册中称为。
乔什·李

10
较新版本的Git甚至可以@^作为的简写HEAD^
Koraktor 2014年

我不知道这是怎么做的,但是我的更改列表上出现了很多文件,而我没有碰过这些文件
FRR 2015年

@feresr如果您确实没有在上一次提交或工作树中触摸这些文件,则是由于工作树中的其他不一致引起的,例如,您在Windows上并且文件结尾不匹配。
Koraktor 2015年

1
是否可以一方面重置所有提交?
Webwoman

185

使用--soft代替--hard标记:

git reset --soft HEAD^

18
您能解释一下这两个标志之间的区别吗?
John Giotta,2015年

1
如果打开Package Manager控制台并运行此“ git reset --soft HEAD ^”,它将完成您想要的(以及我需要的)。
David Cornelson

54
@JohnGiotta- git reset --soft HEAD^将删除上一次本地(未推送)的提交,但将保留您所做的更改
fider 2016年

@fider救主!不确定接受的答案是否仍然有效,但这应该是所需的确切答案。
巴布(Babu)

git reset --soft HEAD~在Windows上
Jack0fshad0ws

34

如果您正在提交之中(即已经在编辑器中),则可以通过删除first上方的所有行来取消它#。那将中止提交。

因此,您可以删除所有行,以使提交消息为空,然后保存文件:

它应该看起来像这样。

然后,您会收到一条消息,内容为Aborting commit due to empty commit message.

编辑

您也可以删除所有行,结果将完全相同。

要删除vim中的所有行(如果这是您的默认编辑器),一旦进入编辑器,请键入gg以转到第一行,然后dG删除所有行。最后,使用写入并退出文件,wq您的提交将被中止。


3
正是我想要的!这个答案需要更多投票:)
jdunk

仅供参考,如果您要中止rebase -i mybranchname
inostia

18

您应该做的第一件事是在删除提交消息之前确定是否要保留本地更改。

使用git log显示当前提交信息,然后找到了commit_id 之前的承诺,你要删除,而不是要删除提交。

如果要保留本地更改的文件,只需删除提交消息:

git reset --soft commit_id

如果要删除所有本地更改的文件和提交消息:

git reset --hard commit_id

这就是区别


1
我认为是相反的。
Ruff9

9

您可以通过使用以下参数之一来告诉Git在执行git reset时如何处理索引(将成为下一个提交的文件集)和工作目录:

--soft:仅将重置提交,而索引和工作目录不变。

--mixed:这将重置索引以匹配HEAD,而不会触摸工作目录。所有更改将保留在工作目录中并显示为已修改。

--hard:它将重置所有内容(提交,索引,工作目录)以匹配HEAD。

在您的情况下,我将把git reset --soft修改后的更改保留在索引和工作目录中。请务必查看此内容以获得更详细的说明。


1

使用以下命令:

$ git reset HEAD~1

此后,您还可以查看文件,如下面的响应一样还原。

Unstaged changes after reset:
M   application/config/config.php
M   application/config/database.php
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.