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