41.1.2 属性文件及优先级
属性文件可以以.gitattributes文件名保存在工作区目录中,提交到版本库后就可以和其他用户共享项目文件的属性设置。属性文件也可以保存在工作区之外,例如保存在文件.git/info/attributes中,则仅对本版本库生效,若保存在/etc/gitattributes[1]文件中则对全局生效。在查询某个工作区某一文件的属性时,不同位置的属性文件具有不同的优先级,Git依据下列顺序依次访问属性文件:
(1)文件.git/info/attributes具有最高的优先级。
(2)接下来检查工作区同一目录下的.gitattributes,并依次向上递归查找.gitattributes文件,直到工作区的根目录。
(3)然后查询由Git的配置变量core.attributesfile指定的全局属性文件。
(4)最后是系统属性文件,即文件$(prefix)/etc/gitattributes。不同的Git安装方式下这个文件的位置可能不同,但是该文件始终和Git的系统配置文件(可以通过git config—system-e命令打开系统配置文件从而知道其位置)位于同一目录中。
注意:只有在1.7.4或更新版本的Git中才提供后两种(全局的和系统级的)属性文件。可以通过下面的例子来理解属性文件的优先级和属性设置方法。
首先来看看某个版本库及系统中所包含的属性文件:
其一是位于版本库中的文件.git/info/attributes,内容如下:
a* foo !bar -baz
其二是位于工作区子目录t下的属性文件,即t/.gitattributes,内容如下:
ab*merge=filfre
abc-foo-bar
*.c frotz
再一个就是位于工作区根目录下的属性文件.gitattributes,内容如下:
abc foo bar baz
如果系统文件/etc/gitconfig中包含如下配置,则每个用户主目录下的.gitattributes文件都被作为全局属性文件。
[core]
attributesfile=~/.gitattributes
位于用户主目录下的属性文件,即文件~/.gitattributes的内容如下:
*text=auto
当查询工作区文件t/abc的属性时,根据属性文件的优先级,按照下列顺序进行检索:
(1)先检查属性文件.git/info/attributes。显然该文件中唯一的一行就和文件t/abc匹配,因此文件t/abc的属性如下:
foo:true
bar:未设置
baz:false
(2)再检查和文件t/abc同目录的属性文件t/.gitattributes。该属性文件的前两行和路径t/abc相匹配,但是因为属性文件.git/info/attributes已经提供了foo和bar的属性,因此第二行对foo和bar属性的设置不起作用。经过这一步,文件t/abc获得的属性为:
foo:true
bar:未设置
baz:false
merge:filfre
(3)然后沿工作区的当前目录向上遍历属性文件,找到工作区根目录下的属性文件.gitattributes进行检查。因为前面的属性文件已经提供了foo、bar和baz属性设置,所以文件t/abc的属性和上面第2步的结果一样。
(4)因为将core.attributesfile设置为~/.gitattributes文件,因此接下来查找用户主目录下的文件即.gitattributes。该文件唯一的一行匹配所有的文件,因此t/abc又被附加了新的属性值text=auto。最终,文件t/abc的属性如下:
foo:true
bar:未设置
baz:false
merge:filfre
text:auto
Git提供了一个查看文件属性设置的命令:git check-attr。针对本例用下面的命令可以查看到文件t/abc各个属性的设置情况。
$git check-attr foo bar baz merge text—t/abc
t/abc:foo:set
t/abc:bar:unspecified
t/abc:baz:unset
t/abc:merge:filfre
t/abc:text:auto
[1]随着Git安装方式的不同,这个文件的位置也可能不同。