我一遍又一遍地看着.gitattributes的文件,但我无法找到关于这两者之间差异的明确答案:
* text=auto
* text eol=lf
同样text=auto
仅适用于*
,还是也可以用于特定扩展程序?在这种情况下,差异是什么?
*.txt text=auto
*.txt text eol=lf
答案 0 :(得分:9)
eol=lf
设置会覆盖任何text
设置,并且由于您已选择将此应用于每个路径,因此只有eol=lf
设置才有用,如果您使用该设置。
让我们从此开始并向外工作:
同样
text=auto
仅适用于*
,还是也可以用于特定扩展程序?
模式可能包含扩展名。 text=auto
部分是属性设置,模式选择要应用于哪些文件的属性。
.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&#34 ;;这是 通过列出仅指定属性的名称 属性列表。
取消设置[已剪切的详细信息,但请参见下文]
设置为值
路径具有指定字符串值的属性;这是 通过列出属性的名称,后跟等于 sign =及其在属性列表中的值。
未指定的
没有模式匹配路径,如果路径有或没有任何说明 没有属性,路径的属性据说 未指定。
(在我看来,这最后一句话的措辞特别差。它的确意味着"所有与该路径相匹配的模式,没有人说过这个属性。")
因此对于text
,属性为 set ,对于text=auto
,属性设置为值。在这种情况下,值部分是auto
。由于模式为*
,因此它适用于所有文件。
同样的逻辑适用于eol=lf
项。如果,首先,此eol=lf
以某种模式发生,其次,该模式与相关文件匹配,则eol
属性设置为值,值为lf
。由于您建议的行为* text eol=lf
,这会将eol
设置为一个值,并使text
设置,但未设置为值
如果您在单个.gitattributes
文件中编写两行序列:
* text=auto
* text eol=elf
第二行的text
会覆盖第一行,以便设置text
(但不会设置值)并将eol
设置为值,值为lf
。两条线匹配,第二条线覆盖第一条线。
如果你反转这两行:
* text eol=lf
* text=auto
然后两行匹配,但现在第二行只覆盖text
设置,所以现在您将text
设置为auto
并{{1设置为eol
。
lf
属性如何应用于文件the gitattributes documentation的下一部分说:
此属性[
text
]启用并控制行尾标准化。 ...... [如果是]
设置...启用行尾标准化并将路径标记为文本文件...
取消设置...告诉Git在签入或结帐时不要尝试任何行尾转换......
设置为字符串值" auto" ......如果Git决定内容是文本......
未指定... Git使用
text
配置变量......
(这意味着,如果您未指定core.autocrlf
,则必须追查the git config
documentation以查找core.autocrlf
的作用。
您已选择为每个文件设置它,或者为每个文件将其设置为text
。前者表示"对每个文件进行转换"后者 - auto
设置 - 意味着:嘿,Git,请为我决定文件是否为文本。如果您确定它是文本,请进行转换。
auto
如何应用于文件 eol=lf
设置的描述正下方是text
设置的说明:
此属性设置要在其中使用的特定行结束样式 工作目录。它可以实现无线端转换 内容检查,有效设置
eol
属性。
- 而剪断了
设置为字符串值" crlf" ... [因为你设置了
text
]设置为字符串值" lf"
此设置强制Git将行结尾标准化为LF on 签入并阻止文件转换为CRLF 签出。
因此,如果您为路径设置了lf
并且使用eol=lf
作为模式,那么将为每个路径设置它 - Git会将每个文件视为文本,并在" checkin"上从CR-LF行结尾转换为仅LF行结尾。 (这是严厉措辞,再次:转换实际上发生在*
步骤)。 Git在结账时不会做任何事情(这也不是完美的措辞:转换 - 或者在这种情况下,非转换 - 在从索引提取到工作树期间发生)。
请注意,如果选择git add
之类的模式,则仅为与模式匹配的路径设置这些属性。对于其他路径,这些属性仍为未设置。因此,您应该回顾the documentation并查看未设置这些属性时会发生什么。
当然,您可以这样做:
*.txt
第一行将在所有文件上明确取消 * -text
*.txt eol=lf
,并在所有文件上未指定text
。第二行然后为eol
文件设置值 eol=lf
,覆盖未指定的值。现在,Git会将*.txt
规则应用于名称与eol=lf
匹配的所有文件,并对所有剩余文件使用unspecified-eol和unset-text规则。
这个特殊的*.txt
语法是我上面提到的内容。使用-text
不会取消设置text=false
:它会将text
设置为字符串值text
。这与留下false
未指定(非具体未设置)具有相同的效果。使用text
会为其提供特殊的未设置设置。
未设置 -text
和未指定 text
之间的区别在于,当text
未指定时,Git可能会尝试 guess - 基于text
设置,例如core.*
- 是否进行转换。当core.autocrlf
专门未设置时,Git不会做任何猜测:它根本不会对该文件进行任何转换。