0

~/foo我在一个文件夹中有一个 GIT 存储库。现在,在bar/那里创建了一个包含一些内容的文件夹,在~/foo/public/bar/. 它被 GIT 正确识别为未跟踪:

~/foo git status -s
?? public/bar/

我一直习惯于git clean -fd删除未跟踪的文件夹,但由于某种原因它不起作用。当我运行它时,什么也没有发生:

~/foo git clean -fd
~/foo git status -s
?? public/bar/

GIT 有什么变化还是我错过了什么?我正在使用 GIT 2.32.0。

4

1 回答 1

0

文件夹本身对 Git 完全不感兴趣:只有文件未被跟踪(因为也只有文件被跟踪)。1 所以当git status说:

?? public/bar/

它隐藏了一些东西。它隐藏的是这样一个事实,即某处下方至少有一个文件。public/bar/

运行git clean -fd不一定会删除这个未跟踪的文件。特别是,如果没有-xor -Xgit 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尽可能利用这一点。但是,当他们必须枚举某些将忽略所有内容的目录中的实际文件时,他们仍然必须打开并读取该目录。

于 2021-06-15T12:02:27.920 回答