git ls-files - 根据文件的 .git ls 文件':(attr:filter=lfs)'查询文件的未记录语法



将 git lfs ls-files 与 git ls-files ':(attr:filter=lfs)' 进行比较是检测不受 LFS 管理的 LFS 文件的可靠方法吗? 使用 git ls-files 语法根据文件的 .gitattributes 查询文件(在 filter=lfs 上的特殊情况下)

git ls-files ':(attr:filter=lfs)'

问题是,尽管它实际上可以正常工作,但文档中并没有对其进行解释 - https://git-scm.com/docs/git-ls-files

那么,这是我在文档中错过的东西,还是一些未记录的功能?

它记录在 gitglossary:

attr:之后会出现一个空格分隔的"属性要求"列表,必须满足所有这些要求才能将路径视为匹配;这是对通常的非魔术 pathspec 模式匹配的补充。

实际上,它记录下来,但不是你所期望的,甚至不是你期待的地方。 记录这一点的地方在 gitglossary 中,在pathspec的定义下:

以冒号开头的路径规范:具有特殊含义......

attr:之后会出现一个空格分隔的"属性要求"列表,必须满足所有这些要求才能将路径视为匹配;

您可以在"git ls-files '(attr:X)D/'"(man)">

的修复中找到其他信息和示例:当它触发公共前缀优化代码路径时,它无法从"D/.gitattributes"读取,并且已在 Git 2.42(2023 年第 3 季度)中进行了更正。

请参阅提交 f4a8fde (2023 年 7 月 8 日),以及提交 7e360bc (2023 年 7 月 7 日),由 Junio C Hamano(gitster).
(由 Junio C Hamano --gitster-- 合并于 提交 13ed10e,2023 年 7 月 17 日)

dir:将"attr"路径规范魔术与正确的路径相匹配

报告人:马修休斯

match_pathspec_item()函数采用"prefix"值,允许调用者从路径中切断路径规范模式字符串的公共前导前缀,并且仅使用路径的其余部分来匹配路径规范模式(当然,在砍掉它们的相同前导前缀之后)。

这种"通用前导前缀"优化有两个主要功能:

  • 丢弃核心索引中公共前导前缀之外的条目;如果你正在执行"ls-files one/a one/b",我们知道所有匹配项都必须来自"one/",所以首先代码会丢弃核心索引中"one/"目录之外的所有条目<。/>这允许我们在较小的数据集上工作。

  • 当将 pathspec
  • 与 pathspec 匹配时,允许跳过前导字节的比较.
    当 "ls-files" 在给定 "one/a" 和 "one/b" 作为路径规范的核心索引中找到路径 "one/a/1" 时,知道找到公共前导前缀 "one/" 让 Pathspec 匹配不需要费心比较 "one/" 部分, 并允许它向下馈送"a/1",只要路径规范元素"one/a"得到相应的调整到"a"。

然而,当"attr"路径规范魔术生效时,当前代码就会崩溃。

除了内置的属性以及来自$GIT_DIR/info/attributes文件和顶级.gitattributes文件的属性之外,这些属性是按需从文件系统中延迟读取的,因为我们遇到每个路径并询问它是否与路径规范匹配。

例如,如果您在存储库中说"git ls-files (attr:label)sub/"(man)",其中文件"sub/file"在"sub/.gitattributes"中被赋予了"label"属性:

  • 公共前缀优化发现"sub/"是公共前缀,并修剪核心索引,使其在该目录中只有条目。
    这是可取的。

  • 然后代码遍历核心索引,找到"sub/file",并最终询问do_match_pathspec()它是否与给定的路径规范匹配。

  • do_match_pathspec()从路径中剥离公共前缀"sub/"后调用match_pathspec_item(),给它"file",加上公共前缀的长度(4字节),这样pathspec元素"(attr:label)sub/"可以被视为"(attr:label)"。

最后一个是破坏当前代码中的匹配,因为pathspec子系统最终要求属性子系统找到附加到路径"file"的属性。

在调用match_pathspec_attrs()时,我们需要询问"sub/file"的属性;这可以通过查看"name"开头之前的"prefix"字节来完成,这与同一match_pathspec_item()函数中另一段代码已经使用的技巧相同。

不幸的是,到目前为止还没有发现这一点,因为代码的参数略有不同,例如

$ git ls-files "(attr:label)sub" 
$ git ls-files "(attr:label)sub/" "no/such/dir/"  

将"sub/file"报告为带有"label"属性的路径,因为两者都不会触发公共前缀优化。

最新更新