我一次又一次地查看.gitattributes的文档,但是找不到关于这两者之间的区别的明确答案:* text=auto
* text eol=lf
text=auto
是否仅打算与*
一起使用还是可以与特定扩展名一起使用?在这种情况下有什么区别?*.txt text=auto
*.txt text eol=lf
最佳答案
TL; DReol=lf
设置将覆盖任何text
设置,并且由于您已选择将其应用于所有路径,因此,如果使用eol=lf
设置,则将很重要。
完整说明
让我们从此开始并逐步进行:
text=auto
是否仅打算与*
一起使用还是可以与特定扩展名一起使用?
模式可以包括扩展名。 text=auto
部分是属性设置,而模式则选择要应用于哪些文件的属性。
Git如何读取.gitattributes
文件.gitattributes
中的每一行都匹配或不匹配某些路径名,例如dir1/dir2/file.ext
或README.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.autocrlf
等text
设置尝试猜测是否进行转换。明确未设置关于git - .gitattributes中的`* text = auto`和`* text eol = lf`有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46590142/