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


1151

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

有人知道该怎么做吗?


1
@Joel和徒步旅行者:你为什么不尝试git help resetgit help clean
SHernandez

3
在您的git config中为此创建一个别名是一个好主意;)
anubina 2015年

Answers:


1698
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


16
注意:git reset --hard删除暂存的更改以及工作目录更改。另外,git clean -f -d可能比添加新的未跟踪文件更好。从这个问题出发,提问者可能会对他当前的被忽略文件感到非常满意。
CB Bailey

7
阅读下一个答案,并注意-x开关。(它也可能会删除您的本地配置,例如密码/数据库设置文件。例如database.yml)
Boris

9
-x开关是不必要的,在这种情况下有些危险。
蒂姆·高铁

66
git clean -fxd如果您不知道自己在做什么,可能会非常危险。您可能最终会永久删除一些非常重要的未跟踪文件,例如数据库等。请谨慎使用。
梅森·斯图尔特

10
请注意,这git clean -f -d也会从忽略的文件夹中删除文件。因此,您所有的本地日志以及类似的内容都将消失。通常这不是一个大问题,但最好知道。
cyriel

299

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

git clean -fd

/docs/git-clean每页的语法说明:

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

如评论中所述,最好先执行git clean -nd一次空运行并告诉您在实际删除之前要删除的内容。

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


124
我总是git clean -nd .在实际删除文件之前使用git clean -fd .
tbear,2012年

14
为什么?请您详细说明一下。
Greg B

31
每个git clean -n选项实际上是一个空运行,它不会删除任何内容,它只是向您显示要执行的操作。
RNickMcCandless 2014年

2
@tbear,你总是可以做一个空白add -A+ commit -a+ revert head第一前git clean。检查每个删除操作根本无法适应主要情况。同样,空转并不是万灵丹:如果您在审查过程中错过了某些东西或犯了错误怎么办?
起搏器

1
这将删除文件,但不会撤消修改。
唐吉x德

201

对于所有未暂存的文件,请使用:

git checkout -- .

.在年底非常重要。

您可以更换 .子目录名称,以仅清除项目的特定子目录。这个问题在这里专门解决。


7
@Vincent:-通过告诉checkout命令不再指定任何参数来避免键入错误。没有它们,您可能会以一个新的分支结尾而不是重置当前分支!
伊戈尔·罗德里格斯

2
这是最安全的路线,但不会删除未跟踪的文件(新添加的文件)。
TinkerTenorSoftwareGuy

5
这不会还原已删除但尚未提交的文件。
Cerin'2

仅供参考。我错过了 确保您在要删除未暂存的更改的目录中。例如,我在分支的不同位置的2个不同文件中进行了更改,即:src/app/work/filename.js../app/working/test/filename.js。仅git checkout -- .在分支上使用仅删除第一个文件(不带前导../)。因此,我必须cd ../进入第二个位置目录才能使用该命令删除第二个文件。
克里斯22年

57

看一下git clean命令。

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

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

通常,仅删除git未知的文件,但是如果指定-x选项,也会删除忽略的文件。例如,这对于删除所有构建产品很有用。


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

42

以下作品:

git add -A .
git stash
git stash drop stash@{0}

请注意,这将同时丢弃您未上演的和已上演的本地更改。因此,在运行这些命令之前,您应该提交任何您想保留的内容。

一个典型的用例:到处移动了许多文件或目录,然后又想回到原始状态。

积分:https : //stackoverflow.com/a/52719/246724


1
为什么要引用stash @ {0}而不是git stash drop
麦凯尔2014年

老实说,我不记得了:)
donquixote 2014年

这个工作了。注意,请确保您位于主目录(git add -A .)中。我丢失了3000万,因为没有文件匹配。谢谢!
user9869932

我曾经使用这种方法,它有优点。但是,从那时起,我发现jfountain和Heath Dutton提出的解决方案更适合最初的问题,恕我直言。
HeyZiko

2
git stash drop stash @ {0}会丢弃最新的stash,如果您执行了git stash,它将删除您所做的所有stash
DonatasD '16

42

您可以分两步执行此操作:

  1. 还原修改的文件: git checkout -f
  2. 删除未跟踪的文件: git clean -fd

3
+1是因为很简单。另外,因为它可以正常运行,并且可以完全按照OP的要求运行,而不会被omg吓跑,所以这将删除所有内容。
geekzster

30

我以为是这样(警告:以下内容清除所有内容

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

reset撤消更改。的clean以除去任何未跟踪˚F尔斯和d irectories。


这行不通,git pull事后我仍然收到冲突警告:CONFLICT (content): Merge conflict in...我只能通过git pull --strategy=ours
rubo77 '16

7
git reset --hard origin/{branchName}

它将删除所有未跟踪的文件。


4

git clean -i首先会向您显示要删除的项目,并在确认后继续进行。在处理不应意外删除的重要文件时,我发现这很有用。

请参阅git help clean以获取更多信息,包括一些其他有用的选项。


4

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

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

用法: git discard


1
我非常喜欢这个别名
标记

3

另一种解决方案是提交更改,然后删除那些提交。起初这并没有立即带来的好处,但是它提供了分批提交并创建git标签进行备份的可能性。

您可以在当前分支上执行此操作,如下所示:

git add (-A) .
git commit -m"DISCARD: Temporary local changes"
git tag archive/local-changes-2015-08-01  # optional
git revert HEAD
git reset HEAD^^

或者,您可以在分离的HEAD上执行此操作。(假设您从BRANCHNAME分支开始):

git checkout --detach HEAD
git add (-A) .
git commit -m"DISCARD: Temporary local changes"
git tag archive/local-changes-2015-08-01  # optional
git checkout BRANCHNAME

但是,我通常要做的是分块提交,然后将部分或全部提交命名为“ DISCARD:...”。然后使用交互式rebase删除错误的提交并保留好的提交。

git add -p  # Add changes in chunks.
git commit -m"DISCARD: Some temporary changes for debugging"
git add -p  # Add more stuff.
git commit -m"Docblock improvements"
git tag archive/local-changes-2015-08-01
git rebase -i (commit id)  # rebase on the commit id before the changes.
  # Remove the commits that say "DISCARD".

这比较冗长,但是可以准确地查看您要放弃的更改。

git lolgit lola快捷方式已经与此工作流程很有帮助。



0

这可能是一个简单的答案,但是:我在Windows上使用TortoiseGit,它具有一个称为REVERT的不错的功能。因此,要还原本地未分段的非推送更改,您需要执行以下操作:

  1. 调出所需文件夹的上下文菜单,然后选择还原,它将显示一个还原弹出窗口,您可以在其中选择更改的文件以还原/恢复。
  2. 如果您还想删除添加的文件(不在git中),请单击“提交”(从同一上下文菜单中),它会弹出“提交”弹出窗口并向您显示添加的文件,然后右键单击每个文件并选择“删除”。但是不要在此弹出窗口中按Commit btn,因为您不想提交,而只能看到已添加的文件并从此处删除它们。
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.