文件夹本身对 Git 完全不感兴趣:只有文件未被跟踪(因为也只有文件被跟踪)。1 所以当git status
说:
?? public/bar/
它隐藏了一些东西。它隐藏的是这样一个事实,即某处下方至少有一个文件。public/bar/
运行git clean -fd
不一定会删除这个未跟踪的文件。特别是,如果没有-x
or -X
,git clean
可以避免删除任何未跟踪时忽略的文件。
正如IMSoP 在评论中提到的那样,使用git status --untracked-files=all --ignored
可以让我们获得更多信息。我们会在public/bar/
. 这里要注意的是,当它可以通过宣布包含目录(带有尾部斜杠)git status
来总结有多个文件时,不需要逐个宣布每个文件。public/bar/
1这并不完全正确,因为有子模块,但它足够接近让人们思考这个问题。此外,文档git clean
在选项的描述下谈到了“未跟踪的目录” -d
,那么这甚至意味着什么?线索在-x
和-X
选项的描述中:
-x
不要使用标准的忽略规则......
通常这里缺少一些东西,这就是忽略规则的工作方式。即使是我截取的部分中提到的 gitignore 文档,也没有涵盖关键细节,即:
- 要查找未跟踪的文件,Git 必须遍历工作树中的文件树。也就是说,它必须查看每个目录(或文件夹,如果您更喜欢该术语)以查看该目录中存在哪些文件。
- 遍历文件树——打开和读取目录以获取文件列表,然后递归地打开和读取每个子目录——速度很慢。
- Gitignore 规则——
.gitignore
文件中忽略特定模式的行——可以列出目录名称,可以使用尾部斜杠显式列出,也可以因为目录名称与某些 gitignore 行匹配而隐式列出。
- 因此,如果 Git 可以提前确定目录中的每个文件——比如
public/bar/
——<em>都将被忽略,那么 Git 可以简单地避免打开该目录并读取它。没有意义:Git 在这里找到的所有内容都将被忽略!
最后一个要点中的快捷方式可以节省时间。在大型构建中,在典型的现代系统上,它可以在运行中节省几秒钟git status
(有时几十秒,甚至更大的数量级)。因此,两者兼而有之git status
,并git clean
尽可能利用这一点。但是,当他们必须枚举某些将忽略所有内容的目录中的实际文件时,他们仍然必须打开并读取该目录。