> For the complete documentation index, see [llms.txt](https://yangsx95.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yangsx95.gitbook.io/notes/version-control/git/gitattributes.md).

# .gitttributes文件

.gitattributes 是一个文本文件，文件中的一行定义一个路径的若干个属性，主要用于定义每种文件的属性，以方便 git 帮我们统一管理。当执行git动作的时候（比如`git commit`），git会自动将目标文件处理为属性的状态。

在.gitattributes文件中，每一行都是一条规则，并且遵循如下规则：

```gitattributes
要匹配的文件模式 属性1 属性2 ...
```

比如github中创建仓库会自动生成如下一个.gitattributes文件：

```gitattributes
# Auto detect text files and perform LF normalization
* text=auto
```

上述文件中 `*` 代表匹配所有的文件，并给所有的文件设置text属性的值为auto。text属性值代表在执行git动作时，将目标文件中的所有换行符规范化，也就是将所有的换行符更换为LF。

.gitattributes文件不仅能给匹配到的文件设置属性，它还可以：

```gitattributes
* text      # 启用text属性
* -text     # 不启用text属性
* text=auto # 启用并设置text属性为auto
*           # 不声明任何属性
* !text     # 不声明text属性值，且覆盖其他文件中的声明
```

在.gitattributes中可以定义的属性主要有：

1. `text` 用于控制行尾的规范性。如果一个文本文件是规范的，则Git库汇总该文件（git 服务器上的文件）的行尾总是LF。对于工作目录，除了text属性之外，还可以设置eol属性或core.eol配置变量。
2. `eol`
   1. `eol=lf` ，`[回车]` ：入库时将行尾规范为LF，检出时行尾不强制转换为 CRLF。
   2. `eol=crlf`，\[换行、回车] ：入库时将行尾规范为LF，检出时将行尾转换为CRLF。
3. `diff` 我们知道 git 主要是用来跟踪文件版本的，跟踪文件版本自然离不开比较差异，而diff 就是用来告诉 git 声明文件需要比较版本差异的。diff属性影响Git对特殊文件生成差异的方式。它可以告诉Git是否为路径生成文本补丁还是将路径视为二进制文件。它也可以影响在hunk头部显示的@@ -k,l +n,m @@，告诉Git使用外部命令来生成差异，或者是在生成差异之前让Git将二进制文件转换为文本文件。
   1. `diff` 强制视为文本文件，即使它包含一些通常从不会出现在文本文件的字节值，例如NUL。
   2. `!diff` 表示为非文本文件，没有设置diff属性的路径会生成differ二进制文件（如果启用了二进制补丁，会生成二进制补丁）。
   3. `未定义` 未指明diff属性的路径首先会检查其内容，如果它看起来像文本文件并且小于大文件阈值（core.bigFileThreshold），则将其视为文本文件，否则将生成differ二进制文件。

示例：

```gitattributes
*           text=auto  
# 文件的行尾自动转换。如果是文本文件，则在文件入Git库时，行尾自动转换为LF。如果已经在入Git库中的文件的行尾是GRLF，则文件在入Git库时，不再转换为LF。

*.txt       text  
# 对于.txt文件，标记为文本文件，并进行行尾规范化。

*.jpg       -text  
# 对于`.jpg`文件，标记为非文本文件

*.vcproj    text eol=crlf 
# 对于.vcproj文件，标记为文本文件，在文件入Git库时进行规范化，行尾转换为LF。在检测到出工作目录时，行尾自动转换为GRLF。

*.sh        text eol=lf  
# 对于sh文件，标记为文本文件，在文件入Git库时进行规范化，即行尾为LF。在检出到工作目录时，行尾也不会转换为CRLF（即保持LF）。

*.py        eol=lf  
# 对于py文件，只针对工作目录中的文件，行尾为LF。
```

生效顺序：

在一个Git库中可以有多个.gitattributes 文件，不同.gitattributes 文件中，属性设置的优先级(从高到低)如下：

* `/myproj/info/attributes` 文件
* `/myproj/my_path/.gitattributes` 文件
* `/myproj/.gitattributes` 文件

同一个.gitattributes 文件中，遵循覆盖原则，即后面的行会覆盖前面的设置，如果一个文件的某个属性被多次设置，则后设置的优先。

根据文件 .gitattributes 中的定义，更新文件的结尾行：

```shell
git rm --cached -r
git reset --hard
```
