如何在提交前撤销 'git add'?

11227

我错误地使用以下命令将文件添加到Git:

git add myfile.txt

我还没有运行git commit命令。我该如何撤销这个操作,以便这些更改不会被提交?


50
从 Git v1.8.4 开始,所有使用 HEADhead 的答案现在可以使用 @ 代替 HEAD。请参见此答案(最后一节)了解为什么可以这样做。 - user456814
5
我做了一个小总结,展示了取消暂存文件的所有方法:https://dev59.com/Dmw05IYBdhLWcg3w9mhW#16044987 - Daniel Alder
8
如果您使用Eclipse,取消勾选提交对话框中的文件就像简单的操作一样。 - Hamzahfrq
2
这是一份来自Github的绝佳资源:如何使用Git撤销(几乎)所有操作 - jasonleonhard
3
在发布新答案之前,请考虑此问题已经有25个以上的答案。确保您的答案提供了现有答案中不存在的内容。 - Sazzad Hissain Khan
显示剩余6条评论
39个回答

15

git add myfile.txt # 这将把你的文件添加到待提交的列表中

与这个命令完全相反的是,

git reset HEAD myfile.txt  # This will undo it.

那么,您将回到之前的状态。指定文件将再次出现在未跟踪列表(之前的状态)中。

它将使用指定文件重置您的HEAD。所以,如果您的HEAD没有该文件,它将只是简单地将其重置。


11
在Sourcetree中,您可以通过图形用户界面轻松完成此操作。 您可以检查Sourcetree用于取消暂存文件的命令。
我创建了一个新文件并将其添加到Git中。然后,我使用Sourcetree GUI取消暂存它。 这是结果:
Unstaging files [08/12/15 10:43] git -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree reset -q -- path/to/file/filename.java
Sourcetree使用reset来取消暂存新文件。

1
是的,相同的技巧也可以用于TortoiseGit,获取常见用例的Git命令。 - Peter Mortensen

10
如果您想撤销最后一次提交但仍希望在本地保留已进行的更改,请使用以下命令:
git reset HEAD~1 --mixed

9

最直观的解决方案之一是使用Sourcetree

您只需从已暂存和未暂存的文件中拖放即可。

输入图像描述


8

我会使用git restore --staged .或者git restore --staged <filename>

你也可以使用git rm --cached,但是git rm命令最好用于已经被跟踪的文件。


8

在 Git 版本 2.23 或之后,您可以使用以下命令:

git restore --staged <filename>

或者,你可以使用这个命令:

git reset HEAD <filename>

欢迎来到Stack Overflow。 如果您决定回答一个已经有了成熟和正确答案的旧问题,那么在一天结束时添加新答案可能不会给您带来任何好处。 如果您有一些独特的新信息,或者您确信其他答案都是错误的,请务必添加新答案,但通常情况下,在问题被提出很久之后再提供相同基本信息的“又一个答案”通常不会为您赢得太多信誉。 - Jonathan Leffler

7
git reset 命令可以帮助你修改暂存区或者同时修改暂存区和工作树。Git 能够像你想要的那样精确地创建提交,这意味着你有时需要撤消使用 git add 添加到暂存区的更改。
你可以通过调用 git reset HEAD <file to change> 来实现。你有两个选项可以完全摆脱更改。 git checkout HEAD <file(s) or path(s)> 是撤消对暂存区和工作树更改的快速方法。
但是,要小心使用该命令,因为它会删除您的工作树中的所有更改。Git 不知道这些更改,因为它们从未被提交过。一旦运行此命令,就无法恢复这些更改。
还有其他可用的命令,例如 git reset --hard。它同样会破坏您的工作树——任何未提交或已暂存的更改在运行后都将丢失。运行 git reset -hard HEAD 与运行 git checkout HEAD 相同。只不过它不需要指定文件或路径来工作。
你可以在 git reset 中使用 --soft。它将仓库重置为您指定的提交,并将所有更改暂存。已经暂存的更改不受影响,工作树中的更改也不受影响。
最后,你可以使用 --mixed 来重置工作树而不暂存任何更改。这也会取消暂存任何已被暂存的更改。

4
第一次遇到这个问题时,我在这篇帖子中找到了解决方法。从第一个答案中,我学到了只需要执行git reset <文件名>就可以了。它很好地解决了问题。
后来,我的主 git 文件夹内有几个子文件夹。我发现只需执行git add .命令添加子文件夹内的所有文件,然后再git reset掉我不想添加的那几个文件即可。
现在我有很多文件和子文件夹了。一个个地执行git reset很烦琐,但通过先执行git add .命令,然后重置那些重且不想添加的文件和文件夹仍然更容易。
我发现以下方法(在这里这里没有记录)相对容易。希望能对你有所帮助:
假设你有以下情况:
Folder/SubFolder1/file1.txt
Folder/SubFolder2/fig1.png
Folder/SubFolderX/fig.svg
Folder/SubFolder3/<manyfiles>
Folder/SubFolder4/<file1.py, file2.py, ..., file60.py, ...>

你希望添加所有文件夹和文件,但不包括 fig1.pngSubFolderXfile60.py,而且该列表会不断增长...

首先创建一个名为 git_add.shbash shell 脚本

接着添加所有要使用 git reset 的文件夹和文件的路径,每个路径前面加上 git reset -- 。随着文件列表的增长,您可以将路径轻松复制粘贴到 git_add.sh 脚本中。 git_add.sh 脚本应该像这样:

#!/bin/bash

git add .
git reset -- Folder/SubFolder2/fig1.png
git reset -- Folder/SubFolderX
git reset -- Folder/SubFolder4/file60.py

#!/bin/bash 很重要。然后执行 source git_add.sh 。之后,你可以执行 git commit -m "一些评论",如果你已经在Bitbucket/Github中设置好了,那么可以执行 git push -u origin master

声明:我只在Linux上测试过这个脚本。


如果你有许多文件和文件夹总是保存在本地git仓库中,但是当你执行git add .时又不想让git跟踪它们的更改,比如视频和数据文件,那么你必须学会使用.gitignore。可以从这里学习。


1
如果您“source”文件,则无需将其设置为可执行文件。 - Jonathan Leffler
你是否考虑使用 .gitignore 文件来防止不应该添加的文件和目录被添加进来? - Jonathan Leffler

3

添加新信息。我的git版本是2.32.1,现在推荐的方法是

git restore --staged <file>...

这是通过输出推荐的

git status

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