Git:撤销所有工作目录更改,包括新文件

1351

如何删除工作目录中的所有更改,包括新的未跟踪文件。我知道git checkout -f可以做到这一点,但是它不会删除自上次提交以来创建的新的未跟踪文件。

有人有任何想法如何做到这一点吗?


1
@Joel和Wayfarer:为什么不尝试使用git help resetgit help clean呢? - SHernandez
3
在你的git配置中为此创建一个别名是个好主意 ;) - anubina
2
我更喜欢使用 git stash(将修改的文件保存在堆栈上)然后使用 git stash drop(删除它)。 - Tiago Martins Peres
13个回答

1969
git reset --hard # removes staged and working directory changes

## !! be very careful with these !!
## you may end up deleting what you don't want to
## read comments and manual.
git clean -f -d # remove untracked
git clean -f -x -d # CAUTION: as above but removes ignored files like config.
git clean -fxd :/ # CAUTION: as above, but cleans untracked and ignored files through the entire repo (without :/, the operation affects only the current directory)

如果您想在实际删除之前查看将要被删除的内容,可以使用-n标志(这基本上是一个测试运行)。当您准备实际删除时,请删除-n标志:

git clean -nfd


17
注意:git reset --hard 命令会删除已暂存的修改以及工作目录中的修改。此外,git clean -f -d 可能是添加新未跟踪文件的更好对应命令。从问题中可以看出,提问者可能对他当前设置的被忽略文件感到满意。 - CB Bailey
7
请查看下一个答案,并注意 -x 开关。它可能会删除您的本地配置文件,例如密码/数据库设置文件(例如 database.yml)。 - Boris
10
在这种情况下,那个 -x 开关是不必要的并有点危险。 - Tim Gautier
76
如果你不知道在做什么的情况下,git clean -fxd实际上可能会非常危险。你可能会永久删除一些非常重要但未被追踪的文件,如你的数据库等。使用时请小心。 - Mason Stewart
13
请注意,git clean -f -d 命令会删除被忽略文件夹中的文件。所以您本地的日志和其他东西都将被删除。通常这不是一个大问题,但最好知道这一点。 - cyriel
显示剩余11条评论

411

最安全的方法,我经常使用:

git clean -fd

根据/docs/git-clean页面的语法解释:

  • -f(别名: --force)。 如果Git配置变量clean.requireForce未设置为false,则git clean将拒绝删除文件或目录,除非给出-f、-n或-i。 Git将拒绝删除带有.git子目录或文件的目录,除非给出第二个-f。
  • -d。 除了未跟踪的文件之外还要删除未跟踪的目录。 如果一个未跟踪的目录由另一个Git存储库管理,则默认情况下不会删除它。 如果您确实想删除这样的目录,请两次使用-f选项。

正如评论中所提到的,最好做一个git clean -nd干扰运行,并在实际删除之前告诉您将删除什么。

git clean文档页面链接:https://git-scm.com/docs/git-clean


147
在执行 git clean -fd . 删除文件前,我总是先执行 git clean -nd . - tbear
15
为什么?你能详细解释一下吗? - Greg B
35
根据 git clean 的说明,-n 选项实际上是个干跑选项,不会删除任何东西,只会展示即将进行的操作。 - RNickMcCandless
2
@tbear,在执行 git clean 命令之前,你可以先进行一个空的 add -A + commit -a + revert head 操作。对于大型场景来说,逐个检查每个删除操作并不太切实际。此外,干运行并不是解决问题的万能药:如果你在检查过程中漏看了某些内容或者出现了错误该怎么办呢? - Pacerier
2
这将删除文件,但不会撤销修改。 - donquixote
1
不回答问题:如何撤消所有更改。运行此操作后,我仍然有所有“修改”和“删除”的更改。 - bradw2k

253

对于所有被追踪但未提交的文件,请使用:

git checkout -- .

末尾的.很重要。

您可以将.替换为子目录名称,以仅清除项目中特定的子目录。这个问题在这里有具体的解决方案。


11
@Vincent:"--"通过告诉checkout命令不再指定更多参数来避免打字错误。如果没有它们,您可能会得到一个新的分支,而不是重置当前分支! - Igor Rodriguez
7
这是最安全的路线,但不会删除未被追踪的文件(即新添加的文件)。 - TinkerTenorSoftwareGuy
10
这并不会恢复已删除但尚未提交的文件。 - Cerin
2
这对我没用。我有未暂存的更改(未暂存以提交),但是 git checkout -- . 没有任何作用。 - Wassadamo
1
这对我没有删除未跟踪的文件。 - Gustavo Maximo
显示剩余3条评论

67

你可以分两步实现:

  1. 撤销已修改的文件:git checkout -f
  2. 删除未追踪的文件:git clean -fd

7
+1 是因为简单易懂。同时它能够完美地满足原帖作者的需求,而不会让他们因为担心数据丢失而退缩。 - geekzster
1
最佳解决方案。不要吓到人们。 - KamyFC

62

查看 git clean 命令。

git-clean - 从工作树中删除未跟踪的文件

递归地从当前目录开始,通过删除不受版本控制的文件来清理工作目录。

通常只会删除 git 不知道的文件,但是如果指定了 -x 选项,则也会删除被忽略的文件。例如,这可以用于删除所有构建产物。


我尝试过 git clean -i 并从菜单中选择了“clean”选项 - 这最终删除了新文件。 - Sany

49
以下内容可正常工作:
git add -A .
git stash
git stash drop stash@{0}
请注意,这将放弃您未提交和已提交的本地更改。因此,在运行这些命令之前,请先提交您想要保留的任何内容。
一个典型的用例是:您移动了许多文件或目录,然后想回到原始状态。
作者署名:https://dev59.com/IXVD5IYBdhLWcg3wNIzc#52719

1
你为什么要引用stash@{0}而不是直接使用git stash drop - maikel
老实说,我不记得了 :) - donquixote
这个有效。顺便提一下,请确保您在主目录中(git add -A .)。我因为没有文件匹配而浪费了30分钟。谢谢! - user9869932
我曾经使用过这种方法,它确实有其优点。然而,我后来发现jfountain和Heath Dutton提出的解决方案更适合原始问题,个人认为。 - HeyZiko
2
git stash drop stash@{0} 如果执行此命令会删除最新的存储,如果你使用 git stash 命令,将删除所有已存储的内容。 - DonatasD
当然使用git stash是最好的方法,因为如果您稍后改变主意,可以使用git stash pop恢复数据。 - Max888

41

我认为这个操作会 (警告:接下来的将会抹掉所有内容)

$ git reset --hard HEAD
$ git clean -fd

reset用于撤销改动。使用clean可删除任何未跟踪的f文件和d目录。


这个不行,之后执行 git pull 仍然会得到冲突警告:CONFLICT (content): Merge conflict in... 我只能通过执行 git pull --strategy=ours 来解决这个问题。 - rubo77

7
git reset --hard origin/{branchName}

它会删除所有未追踪的文件。

5

git clean -i 命令会先展示需要删除的文件,等待你确认后再进行删除。在处理不应被意外删除的重要文件时,我发现这个命令非常有用。

更多信息请参见 git help clean,其中包含一些其他有用的选项。


4

如果您想放弃所有更改,您可以在.gitconfig的别名中使用任何有效选项。例如:

[alias]
    discard = "!f() { git add . && git stash && git stash drop stash@{0}; }; f"

使用方法:git discard

1
我非常喜欢这个别名。 - flags

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