将 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
"值,允许调用者从路径中切断路径规范模式字符串的公共前导前缀,并且仅使用路径的其余部分来匹配路径规范模式(当然,在砍掉它们的相同前导前缀之后)。这种"通用前导前缀"优化有两个主要功能:
- 当将 pathspec
丢弃核心索引中公共前导前缀之外的条目;如果你正在执行"
ls-files one/a one/b
",我们知道所有匹配项都必须来自"one/
",所以首先代码会丢弃核心索引中"one/
"目录之外的所有条目<。/>这允许我们在较小的数据集上工作。与 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
"属性的路径,因为两者都不会触发公共前缀优化。