git - .gitattributes中的`* text = auto`和`* text eol = lf`有什么区别?

标签 git gitattributes core.autocrlf

我一次又一次地查看.gitattributes的文档,但是找不到关于这两者之间的区别的明确答案:

* text=auto

* text eol=lf

text=auto是否仅打算与*一起使用还是可以与特定扩展名一起使用?在这种情况下有什么区别?

*.txt text=auto

*.txt text eol=lf

最佳答案

TL; DR

eol=lf设置将覆盖任何text设置,并且由于您已选择将其应用于所有路径,因此,如果使用eol=lf设置,则将很重要。

完整说明

让我们从此开始并逐步进行:


text=auto是否仅打算与*一起使用还是可以与特定扩展名一起使用?


模式可以包括扩展名。 text=auto部分是属性设置,而模式则选择要应用于哪些文件的属性。

Git如何读取.gitattributes文件

.gitattributes中的每一行都匹配或不匹配某些路径名,例如dir1/dir2/file.extREADME.md或其他。正如the gitattributes documentation所说:


gitattributes文件中的每一行都是以下形式:

pattern attr1 attr2 ...


即,模式后面是属性列表,由空格隔开。前导和尾随空格将被忽略。以#开头的行将被忽略。以双引号开头的模式以C样式引用。当模式与所讨论的路径匹配时,将在行上列出的属性赋予该路径。


因此,*是模式。这些“模式”为the same as those in .gitignore files,但不允许使用否定模式。因此,您可以使用*.txt*.jpg之类的模式来匹配文件扩展名,或者使用dir1/*之类的模式来匹配特定目录中的文件(尽管还有另一种方式可以做到:像.gitignore文件一样,您可以每个目录中可以有.gitattributes个文件,在这种情况下,它们适用于该目录及其子目录中的文件,但不适用于树中更高的路径。

现在,对于text vs text=auto,对于eol=lf与否,我们发现以下内容:


对于给定的路径,每个属性可以处于以下状态之一:




路径具有带有特殊值“ true”的属性;这是
通过仅在列表中列出属性名称来指定
属性列表。
未设置[详细信息已删除,但请参见下文]
设置为一个值

路径具有具有指定字符串值的属性;这是
通过列出属性名称后跟等号来指定
sign =及其值在属性列表中。
未指定

没有模式与路径匹配,并且没有说明路径是否具有或
没有属性,据说路径的属性是
未指定。



(在我看来,这最后一个措辞特别糟糕。它的真正含义是“在与路径匹配的所有模式中,没有任何关于此属性的内容。”)

因此,对于text,将设置属性,对于text=auto,将属性设置为值。在这种情况下,值部分为auto。由于模式是*,因此它适用于所有文件。

此相同的逻辑适用于eol=lf项。如果首先,此eol=lf以某种模式出现,其次,该模式与所讨论的文件匹配,则将eol属性设置为一个值,并且该值为lf。由于建议的行是* text eol=lf,因此这会将eol设置为一个值,并且将text设置为但不设置为一个值。

如果在单个.gitattributes文件中写入以下两个行序列:

* text=auto
* text eol=lf


第二行的text覆盖第一行的text,因此将eol设置为(但不设置为值),将lf设置为一个值,该值为text。两条线都匹配,第二条线覆盖了第一条线。

如果将这两行颠倒:

* text eol=lf
* text=auto


然后两行再次匹配,但是现在第二行仅覆盖text设置,因此现在您已将auto设置为eol,并且将lf设置为text

text属性如何应用于文件

the gitattributes documentation的下一部分说:


此属性[core.autocrlf]启用并控制行尾规范化。 ... [如果是]


Set ...启用行尾规范化并将路径标记为文本文件...
未设置...告诉Git在签入或签出时不要尝试任何行尾转换...
设置为字符串值“自动” ...如果Git确定内容为文本...
未指定... Git使用git config配置变量...



(这意味着,如果您未指定core.autocrlf,则必须追踪the text documentation来找出auto的功能)。

您已选择为每个文件设置它,或为每个文件将其设置为auto。前者的意思是“对每个文件进行转换”,而后者的意思是eol=lf设置,意思是:嘿,Git,请为我确定文件是否为文本。如果您确定它是文本,请执行转换。

text如何应用于文件

eol设置的描述正下方是text设置的描述:


此属性设置要在
工作目录。它支持行尾转换,而无需任何
内容检查,有效地设置lf属性。


设置为字符串值“ crlf” ... [由于设置了eol=lf而被删除]
设置为字符串值“ lf”

此设置强制Git将行尾标准化为LF
签入并防止在文件为
检查过了。



因此,如果您为路径设置了*-并且以git add为模式,则将为每个路径设置-Git将把每个文件都视为文本,并执行从CR-LF行尾到LF-的转换。仅行尾在“ checkin”上(这是措辞不好的一遍:转换实际上发生在*.txt步骤中)。 Git在结帐期间将不执行任何操作(这也不是完美的措辞:在从索引到工作树的提取期间,转换(或在这种情况下为非转换)发生)。

如果使用不同的模式,则会得到不同的结果

请注意,如果选择类似text的模式,则仅为与该模式匹配的路径设置这些属性。对于其他路径,这些属性保持不变。因此,您应该回顾the documentation并查看未设置这些属性时会发生什么。

您当然可以这样做:

* -text
*.txt eol=lf


第一行将在所有文件上显式取消设置eol,而在所有文件上未指定eol=lf。然后,第二行将*.txt文件的值设置为eol=lf,覆盖未指定的值。现在,Git将*.txt规则应用于名称与-text匹配的所有文件,并对其余所有文件使用unspecified-eol和unset-text规则。

这种特殊的text=false语法是我上面提到的内容。使用text不会取消设置text:它将false设置为字符串值text。这与未指定-text(未明确设置)的效果相同。使用text为它提供特殊的未设置。

未设置的text和未指定的text之间的区别在于,当未指定core.*时,Git可能会根据core.autocrlftext设置尝试猜测是否进行转换。明确未设置时,Git不会做任何猜测:它将完全不对该文件进行任何转换。

关于git - .gitattributes中的`* text = auto`和`* text eol = lf`有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46590142/

相关文章:

git - 如何规范 Git 中的工作树行结尾?

c# - 引入 Visual Studio 2015 的问题

git - 让 git 只跟踪文件中的某些行

git - 有没有办法在终端中列出所有 git 存储库?

windows - git EOL 以相反的方式转换? (尽管 .gitattributes)

git - 不对 .m matlab 文件进行 git CRLF 转换?

git - 如何用.gitattributes表示core.autocrlf = false?

git - 在使用 "text"属性规范化文件后,如何强制 git check out 主分支并删除回车符?

git - bash 中的函数提交并推送一个命令

linux - Git 大文件存储/如何在 AWS EC2 Linux 上安装 git lfs 2/"No package git-lfs available."