如何从当前的Git工作树中删除本地(未跟踪)文件?

8044

我该如何从当前的工作树中删除未被跟踪的本地文件?


102
这个互动的 git 命令速查表 http://www.ndpsoftware.com/git-cheatsheet.html 展示了 git 工作区(使用 "workspace" 而非 "working copy" 可以获得更好的谷歌搜索结果)。 - qneill
36
注意:如果您只想删除部分未跟踪的文件,而不是全部git clean现在有一个交互模式!请参见我对另一个问题的答案:git 1.8.4+ - VonC
在发布新答案之前,请考虑该问题已经有25个以上的答案。确保你的答案提供了现有答案中没有的信息。 - Sazzad Hissain Khan
8
为了让初学者和新手更好理解 Git,可以运行 git status 命令,如果它显示有一个文件未被跟踪,并且你不想将该文件添加到版本库中,你可以直接在文件系统中删除或移动它。这样不会对你的本地仓库或 Git 造成任何损害。你也可以使用 git clean 或以下答案中的某些变体,包括交互式版本,以仅删除选择的文件,但交互模式可能很繁琐。无论你做什么,一定要确保你理解 git clean 将删除哪些内容,或使用 --dry-run 让它告诉你而不会真正执行删除操作。 - LightCC
6
如果这些文件尚未被跟踪,你是否可以在不使用git的情况下删除它们呢?rm files-to-be-deleted - mhatch
Git现在提供交互模式,可以有选择性地删除特定的未跟踪文件,允许您选择要删除哪些文件,同时保留其他文件不受影响。 - Dmitrii Malygin
41个回答

9745

git-clean - Remove untracked files from the working tree

Synopsis

git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>…​

Description

Cleans the working tree by recursively removing files that are not under version control, starting from the current directory.

Normally, only files unknown to Git are removed, but if the -x option is specified, ignored files are also removed. This can, for example, be useful to remove all build products.

If any optional <path>... arguments are given, only those paths are affected.


第一步是使用-n选项显示将被删除的内容:

# Print out the list of files and directories which will be removed (dry run)
git clean -n -d

清理步骤 - 注意:这将删除文件

# Delete the files from the repository
git clean -f
  • 要删除目录,请运行 git clean -f -dgit clean -fd
  • 要删除被忽略的文件,请运行 git clean -f -Xgit clean -fX
  • 要删除被忽略和未被忽略的文件,请运行 git clean -f -xgit clean -fx

注意后两个命令中X的大小写不同。

如果在您的配置中设置了clean.requireForce为“true”(默认值),则需要指定-f,否则实际上什么也不会发生。

有关更多信息,请参见git-clean文档。


选项

-f--force

如果 Git 配置变量 clean.requireForce 没有设置为 false,则 git clean 将拒绝运行,除非给出 -f-n-i

-x

不使用从 .gitignore(每个目录)和 $GIT_DIR/info/exclude 读取的标准忽略规则,但仍然使用使用 -e 选项给出的忽略规则。这允许删除所有未跟踪的文件,包括构建产品。这可以与 git reset 结合使用,创建一个原始的工作目录来测试干净的构建。

-X

仅删除 Git 忽略的文件。这可能对于从头开始重建一切但保留手动创建的文件很有用。

-n--dry-run

不要实际删除任何内容,只是显示将要执行的操作。

-d

除了未跟踪的文件外,还删除未跟踪的目录。如果未跟踪的目录由另一个 Git 存储库管理,则默认情况下不会删除它。如果您真的想删除这样的目录,请两次使用 -f 选项。


353
git clean -f 只在被调用的目录及其子目录中生效。如果你想清理整个工作副本,应该在其根目录下调用该命令。 - Eduardo Bezerra
24
它会删除 .gitignore 中指定的所有文件。我只需要删除那些新建的、未在 .gitignore 中列出的文件或文件夹。 - Kostanos
30
如果您不想删除在 .gitignore 文件中的文件,则不要提供 -x 标志。 - Lo-Tan
66
git clean -f :/ 的作用类似于在根仓库目录下运行它。还可以使用 git clean -ffxd :/ 来考虑子模块。请参考后续答案。 - here
4
在苦苦挣扎并咒骂了45分钟后,我发现了@EduardoBezerra的评论... 我认为原帖应该编辑回答来强调git clean的行为——只删除当前目录及其子目录中的文件。这一点在git帮助文档和回答本身中都不太清楚。 - Motti Shneor
显示剩余5条评论

1257

使用git clean -n命令可以查看将会被删除的文件,但不执行实际删除操作。

  1. 并不真正移除任何东西,只是显示将要执行的操作。

git clean -n
或者
git clean --dry-run
  • 除了未跟踪的文件外,还可以删除未跟踪的目录。如果未跟踪的目录由另一个Git存储库管理,则默认情况下不会将其删除。如果确实想要删除这样的目录,请两次使用-f选项。

  • git clean -fd
    
    你可以使用 git status 命令检查你的文件是否真的被删除了。

    126
    如先前所述,最好使用 git clean -n -d 进行干运行。 - Ms01
    17
    执行 git clean -ndgit clean -fd 的效果是相同的。 - Micer
    仅使用 -n--dry-run 并没有任何作用。根据 @Ms01 和 @Micer 的建议,您需要添加 -d,例如 git clean -nd 来显示它将要删除的内容。 - joehanna

    562

    我很惊讶之前没有人提到过这点:

    git clean -i
    

    这代表着交互式,你将会快速了解将要被删除的内容,并提供包括/排除受影响文件的可能性。总体而言,比在真正清理前运行强制的--dry-run还要快。

    如果你也想处理空文件夹,那么你需要加上-d。最后,它能够成为一个很好的别名:

    git iclean
    

    话虽如此,交互式命令的额外辅助可能会让经验丰富的用户感到疲倦。最近,我只是使用已经提到的git clean -fd命令。


    18
    它是在1.8.4版本中添加的,你可能正在运行一个更旧的git版本?https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.4.txt - Mattias Backman
    我喜欢这个 - 我更喜欢将它放在我的bash历史记录中,而不是其他选项,因为如果我意外地按下ctrl-r或ctrl-p,这并不是什么大问题。 - csvoss
    1
    git clean -i 只有在工作副本的根目录下调用才有效吗? - Alessandro Jacopson

    417

    git clean -f '未被追踪的文件路径' - Hossain Mahmood Tuhin

    389

    简单的删除未跟踪文件方法

    要删除所有未跟踪的文件,简单的方法是首先将它们全部添加,然后像下面这样重置仓库

    git add --all
    git reset --hard HEAD
    


    13
    你可以用git add .来代替git add --all。因此,你可以使用一行命令git add . && git reset --hard HEAD来更简便地执行此操作(请注意,这个命令要非常小心)。 - alexandre-rousseau
    12
    因为 git clean 命令会连同被忽略的文件一并删除,所以它刚刚删除了我的 node_modules 文件夹。如果要避免这种情况发生,可以先将所有非被忽略的文件加入暂存区,然后使用重置命令删除它们。被忽略的文件将不会受到影响。 - Andreas
    5
    @Andreas,对我来说它不会删除被忽略的文件(git 2.14.1)。在进行实际删除之前,你应该无论如何都运行git clean -n(参见这里),或者使用git clean -i(参见这里)。 - Qw3ry
    13
    git clean 命令仅在使用 -x-X 选项时才会删除被忽略的文件,否则它只会删除未被跟踪的文件。 - doubleDown
    4
    git add . 只会将当前目录及其子目录下的文件添加到暂存区,而 git add --all 会将整个仓库的文件都添加到暂存区。后者似乎是更安全的选择。 - TrueWill
    显示剩余6条评论

    303

    如果未被跟踪的目录是一个独立的 git 子仓库(例如,子模块),则需要使用两个 -f

    git clean -d -f -f


    7
    顺便提一下,这是在文档中写的:Git不会删除带有.git子目录或文件的目录,除非使用第二个-f选项。但无论如何还是谢谢! - Maxim Suslov
    @MaximSuslov如果文档像您的评论建议的那样有帮助,那么在SO上提出的问题将会显著减少。但无论如何感谢您! - blackbox
    在运行之前,您可能需要将目录更改为根文件夹,例如 cdgit rev-parse --show-toplevel - Mark Kahn

    165

    这是我经常使用的:

    git clean -fdx
    

    对于一个非常大的项目,您可能需要运行它几次。


    @Martin 我正在从事的一个项目已经有8年历史,有80多个开发人员正在积极编码。Git有时第一次无法成功清理它。 - Oscar Fraxedas
    1
    我可以确认这一点,所以在2020年仍然有效。我们也正在进行一个大项目,我不得不运行它4-5次,直到GIT找不到要删除的文件为止。 - turbolocust
    需要记住的主要事情是,上述命令仅适用于您所在的目录。因此,如果您在子文件夹中运行上述命令,则不会从父文件夹或其他子文件夹中删除未跟踪的文件。 - A Yashwanth

    161

    我喜欢使用git stash push -u,因为你可以使用git stash pop撤销所有的操作。

    编辑:我还发现了一种方法,可以在stash中显示未跟踪的文件(例如git show stash@{0}^3https://dev59.com/Q2cs5IYBdhLWcg3wp1pW#12681856

    编辑2:git stash save已经被废弃,推荐使用push。谢谢@script-wolf提供的信息。


    3
    你能解释一下stash中的“-u”是什么意思吗?我不明白它和git stash save有什么区别。我试过了,好像可以用。我在git文档里也找不到相关信息。 - Winnemucca
    11
    -u 相当于 --include-untracked。您可以通过 git help stash 查找帮助。 - hiroshi
    3
    @hiroshi 谢谢!尝试了十几个人提供的各种解决方案后,这个终于奏效了... 哎呀!即使使用 git stash 也没用。save - u 搞定了未跟踪的文件。reset hard/clean force/等等,这些对我都没有用。 - killjoy
    3
    save选项已被弃用,push取代了它并且具有相同的功能,但更多。您可以在此处阅读更多信息:https://dev59.com/NFcP5IYBdhLWcg3wP32t#44681952 - Script Wolf

    137

    在运行`git clean`命令时要小心。

    始终首先使用-n

    运行clean命令之前,始终使用-n,它会显示将被删除的文件列表。

    -d通常,如果未指定,则git clean不会递归进入未跟踪的目录以避免删除过多。 指定-d可以使其递归到这些目录中。 如果指定了任何路径,则-d无关紧要; 将删除与指定路径匹配的所有未跟踪文件(在--force下提到的嵌套git目录有例外)。

    -f|--force 如果Git配置变量clean.requireForce未设置为false,则git clean将拒绝删除文件或目录,除非给出-f-i。 Git将拒绝修改未跟踪的嵌套git存储库(具有.git子目录的目录),除非给出第二个-f

    git clean -n -d 
    git clean -n -d -f
    

    如果输出是您打算删除的内容,则现在可以不使用-n运行。

    git clean -d -f
    

    默认情况下,git clean仅会删除未被跟踪且未被忽略的文件。匹配你的 .gitignore 或其他忽略文件中模式的文件不会被删除。如果你想要同时删除这些文件,你可以在清理命令后添加 -x

    git clean -f -d -x
    

    清理命令还提供交互模式-i

    git clean -x -i
    

    或者

    如果您不确定删除未提交的工作是否安全,您可以使用存储来代替。
    git stash --all
    

    使用 stash --all 前请注意: 如果使用了 --all 选项,则除了未跟踪的文件外,还会存储和清理被忽略的文件

    git stash push --keep-index
    
    如果使用了--keep-index选项,则已添加到索引的所有更改都会保持不变。您暂存的更改仍然在你的工作区中,但同时也保存到了你的贮藏中。
    调用git stash而没有任何参数等同于git stash push
    git stash push -m "name your stash" // before git stash save (deprecated)
    

    根据使用的标记进行暂存可以通过将文件写入藏匿存储,从而清除您的目录中未提交/已提交的文件。这使得您可以使用applypopstash在任何时间点检索文件。然后,如果您想删除已经暂存的文件,您可以运行:

    git stash drop // or clean
    

    要查看如何使用stash的完整说明,请参阅此在Git中如何按名称命名和检索stash?

    输入图像描述


    2
    储藏是个好主意,不过你可能想使用 git stash save 并输入一些注释来说明这个储藏的用途。 - lacostenycoder
    我有大约20张图片想从各个目录中删除,但是git stash --all却移除了数千个文件并破坏了我的项目。这是怎么回事?它甚至移除了vendor目录。我会谨慎使用这个命令。幸运的是,我在本地repo(仓库)中操作,而不是在生产环境中。 - warmwhisky
    git stash --all 将会移除 Laravel 中的 vendor 目录、node_modules、.env 和 storage 文件,以及其他我可能遗漏的文件。我必须重新运行 composer install,重新创建我的 .env 文件并在 storage 中重新创建缓存文件夹。这是一个可怕的想法,除非你想要删除未跟踪的文件以及所有在 .gitignore 文件中的内容。 - warmwhisky
    1
    较新的 Git 版本可以使用 git stash push,该命令还能够存储未跟踪的文件。 - Holger Böhnke

    111

    git-clean 是您需要寻找的工具,用于从工作区中删除未跟踪的文件。


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