gpt4 book ai didi

git - 在 gitattributes 中使用 `**/` 匹配目录

转载 作者:行者123 更新时间:2023-12-04 09:36:39 26 4
gpt4 key购买 nike

我在期待 **/匹配 git repo 中的任何目录,但实际上它什么都不匹配。 man gitattributes说:

patterns that match a directory do not recursively match paths inside that directory (so using thetrailing-slash path/ syntax is pointless in an attributes file; use path/** instead)


但就我而言 **/甚至与目录本身不匹配。我的意思是,如果我有 a/b.txt在我的 repo 中,然后 **/甚至不匹配目录 a .我期待它匹配目录 a但不是文件 a/b.txt .
如果我改变 **/** ,则目录及其内容都匹配。在同一个例子中,两个目录 a和文件 a/b.txt匹配。
那么 gitattributes 如何在目录上工作呢?如果 git 认为目录上的属性无关紧要,那么在 ** 的情况下,git 为什么要列出它们? ?

最佳答案

不像 .gitignore ,它进行特殊情况目录处理,看来 .gitattributes代码从不特例目录。这部分是因为 Git 并不真正存储目录。1 所以每个属性都应用于某些文件集。尽管如此,文件确实驻留在目录中——在两个真实的操作系统中,以及它们在提交中的存储方式(见脚注 1)——所以它可能对 .gitattributes 有意义。对尾部斜杠有一个特殊情况,而不是将该属性应用于文件。
但是,正如您所观察到的,这不会发生。尽管 attr.c 中有一些代码(在 path_matches 中)检查目录。但这并不重要,因为 Git 属性的有用部分无论如何都只适用于文件。
我上面强调的文字是这个意思。考虑,例如:

*.txt    text
*.jpg -text diff=jpg
version export-subst
这可能会在一些 .gitattributes 中找到文件。这告诉 Git *.txt文件是文本,因此任何 CRLF 转换都适用,而 *.jpg文件是二进制的,它们不会(差异将使用“jpg”差异驱动程序生成:参见 gitattributes )。 version文件将在执行 git archive 时执行哈希 ID 替换.所有这些操作都发生在文件上。如果我们有:
sub/    -text
这根本什么都不做,因为目录 sub永远不会出现在 Git 的索引中(因此影响索引/工作树转换的操作不适用),并且只会在 Git 存储库中存储为一棵树(再次参见脚注),您(用户)没有可用的操作或选项。如果您想要 sub 内的文件要被视为二进制文件,您可以编写:
sub/*    -text
sub/**/* -text
诚然,这是两行,如果 Git 允许,其中一行会提供 sub/作为这里的模式。因此,能够通过目录前缀来命名文件可能有些用处,但缺乏这种能力并不是一个严重的问题。

1当 Git 进行提交时,Git 会为文件和子目录的顶级目录创建一个树对象,并为每个包含文件的子目录再创建一个树对象。它基于 Git 索引的内容进行操作,该索引不存储目录本身。索引仅存储文件。
从技术上讲,索引中的内容是每个文件的信息元组: 。您可以通过运行 git ls-files --stage 来查看此信息。 .这增加了缓存数据和标志 - 您也可以通过添加 --debug 来查看大部分内容。到 git ls-files命令——但四元组,阶段号通常为零,是索引的关键部分。以下是来自 Git 本身的 Git 存储库索引的示例:
100644 c2f5fe385af1bbc161f6c010bdcf0048ab6671ed 0       .cirrus.yml
100644 c592dda681fecfaa6bf64fb3f539eafaf4123ed8 0 .clang-format
100644 f9d819623d832113014dd5d5366e8ee44ac9666a 0 .editorconfig
100644 b08a1416d86012134f823fe51443f498f4911909 0 .gitattributes
100644 e7b4e2f3c204c2c94c60222abbc702bd7d72de39 0 .github/CONTRIBUTING.md
100644 952c7c3a2aa11ea1087390be61eab6f7c0013599 0 .github/PULL_REQUEST_TEMPLATE.md
100644 84a5dcff7a05fb724d78826212c5fa22ba5df958 0 .github/workflows/main.yml
100644 ee509a2ad263989fcebe3c3543aa32efed1cacda 0 .gitignore
100644 cbeebdab7a5e2c6afec338c3534930f569c90f63 0 .gitmodules
100644 bde7aba756ea74c3af562874ab5c81a829e43c83 0 .mailmap
只要所有文件都在零阶段,Git 就可以将索引转换为树对象。树对象在那些看起来有目录名的条目之上包含一个子树,例如 .github/*文件。在索引中,目录不存在:文件只是命名为 .github/CONTRIBUTING.md等等。然而,在一次提交中,它们变成了子树。请注意,一个文件名为 github/workflows/main.yml ,所以 .github sub-tree 将包含一个名为 workflows 的子子树将包含 main.yml文件。
从某种意义上说,Git 以类似目录树的方式存储文件,然后;但它使用文件,当你在你的存储库中工作时,不考虑目录,因为索引将目录扁平化。这可能有点设计错误,因为这是 Git 无法正确存储空目录的主要原因。 (已经进行了各种尝试来解决这个问题,唯一可以正常工作的方法——使用空子模块——非常笨拙。)

关于git - 在 gitattributes 中使用 `**/` 匹配目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62548768/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com