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安装方式的不同,这个文件的位置也可能不同。