跳到主要内容

.gitattributes 特定版本控制规则

配置 Git 属性,可以对特定的子目录或子文件运用特定的版本控制规则,如:

  • 对二进制文件、文本文件的变更内容采用不同的对比 (Diff) 方式
  • 对文件或目录定义不同的合并 (Merge) 策略
  • 在提交 (Commit) 或检出 (Checkout) 前过滤内容

本文围绕文件“对比”和“合并”展开,“内容过滤”应用场景少之又少,自行参考官方文档吧。

Git 属性配置文件为 .gitattributes,在仓库根目录下。

不同的 Diff 方式

文件有文本文件、二进制文件,Git 采用不同的方式对文件内容进行对比,以找出差异。

处理二进制文件

比如,一些文本文件是由机器产生的,没有办法进行比较,而一些二进制文件可以比较,因此,一些场景下,需要配置 Git 属性,让 Git 能区分这些文件。

例如,一些图形文件 (.png.gif)、机器处理文件 (.class.pbxproj),我们不会将它们当作文本文件来处理,即便有冲突,也无法合并内容,因此,我们会将其当成二进制文件。

我们可以配置:

*.class           binary

# Graphics
*.jpg binary
$ git diff
diff --git a/feature.class b/feature.class # 二进制类文件的 diff
index 01e79c3..94ebaf9 100644
Binary files a/feature.class and b/feature.class differ
diff --git a/feature.txt b/feature.txt # 文本类文件的 diff
index 9d091c7..262ad6c 100644
--- a/feature.txt
+++ b/feature.txt
@@ -1 +1,2 @@
第一次提交
+第二次提交

对 Microsoft Word 文档进行版本控制

另外,可以使用 Git 属性来比较二进制文件,需要通过特殊的方式将二进制文件转化为文本格式,从而使 Git 能用普通的 diff 方式进行对比。

默认的二进制文件比较信息:

$ git diff
diff --git a/feature.docx b/feature.docx
index 930096e..64d23f0 100644
Binary files a/feature.docx and b/feature.docx differ

比如,想对 .docx 文档进行版本控制,我们可以下载 docx2txt,用 7z 解压出来文件放到 C:\Tool\docx2txt 目录下,然后配置环境变量 —— 通过运行 sysdm.cpl 打开“系统属性”面板,在“高级”选项卡中打开“环境变量”,将 C:\Tool\docx2txt 加入到“系统变量” Path 中。

接着在 docx2txt 目录中用 Git Bash 执行 touch docx2txt 创建一个文件,用编辑器打开,复制和保存以下内容:

#!/bin/bash
docx2txt.pl "$1" -

通过 chmod a+x docx2txt 给这个文件加上可执行权限。

然后配置 Git 来使用 docx2txt 这个脚本:

git config --global diff.word.textconv docx2txt

通过上述方式,Git 能将 Word 文件转换成文本文件并进行比较:

$ git diff
diff --git a/feature.docx b/feature.docx
index 9391029..5694f87 100644
--- a/feature.docx
+++ b/feature.docx
@@ -1 +1,2 @@
第一次提交
+第二次提交

比较图像文件

图像文件比较可运用一个过滤器,提炼出 EXIF 信息,查看图片元数据的变更。

默认的二进制文件比较信息:

$ git diff
diff --git a/feature.jpg b/feature.jpg
index 92b3766..22adbdb 100644
Binary files a/feature.jpg and b/feature.jpg differ

下载 exiftool,解压到 C:\Tool\exiftool 目录,重命名为 exiftool.ext,然后配置环境变量,方法同上。

配置 .gitconfig

git config --global diff.exif.textconv exiftool

然后在仓库 .gitattributes 文件中配置:

*.jpg             diff=exif

对比图像文件能得到元数据变更信息:

$ git diff -p
diff --git a/feature.jpg b/feature.jpg
index 92b3766..22adbdb 100644
--- a/feature.jpg
+++ b/feature.jpg
@@ -1,10 +1,10 @@
ExifTool Version Number : 12.49
File Name : feature.jpg
-Directory : C:/Users/Xiang/AppData/Local/Temp/git-blob-a16464
-File Size : 5.1 MB
-File Modification Date/Time : 2022:10:22 15:23:16+08:00
+Directory : .^M
+File Size : 5.7 MB^M
+File Modification Date/Time : 2022:03:21 18:24:58+08:00^M
File Access Date/Time : 2022:10:22 15:23:16+08:00
-File Creation Date/Time : 2022:10:22 15:23:16+08:00
+File Creation Date/Time : 2022:10:22 15:17:39+08:00^M

不同的 Merge 策略

通过配置 Git 属性可以对特定文件指定不同的合并策略,当特定文件发生冲突时,可以告诉 Git 不要尝试合并它们,而是直接使用当前分支的内容。

例如分支 featuredevelop 中都有一个 database.xml 文件,在不同分支中内容不同,从 feature 合并进 develop 分支时,不想 database.xml 产生变更,可以进行如下配置:

.gitconfig 中定义一个虚拟的合并策略。

git config --global merge.ours.driver true

然后在仓库 .gitattributes 文件中配置:

database.xml merge=ours

这样,在 develop 合并 feature 分支时,提示:

$ git merge feature
Auto-merging database.xml
Merge made by the 'ort' strategy.

develop 中的 database.xml 文件内容则不会变更。

Resources