Contents
Open Contents
前言
过去进行git仓库管理时,一直没有太在意.gitignore与.gitattributes这两个配置文件,为此记录一下这两个文件的作用与用法。
.gitignore
.gitignore 文件用于告诉 Git 哪些文件或目录不需要纳入版本控制。常用于排除编译生成文件、依赖包、临时文件等。
在 .gitignore 文件中,每一行的忽略规则的语法如下:
- 空格不匹配任意文件,可作为分隔符,可用反斜杠转义;
- 以
#开头的行都会被 Git 忽略。即#开头的文件标识注释,可以使用反斜杠进行转义; - 可以使用标准的glob模式匹配。所谓的glob模式是指shell所使用的简化了的正则表达式;
- 以斜杠
/开头表示目录;/结束的模式只匹配文件夹以及在该文件夹路径下的内容,但是不匹配该文件;/开始的模式匹配项目跟目录;如果一个模式不包含斜杠,则它匹配相对于当前 .gitignore 文件路径的内容,如果该模式不在 .gitignore 文件中,则相对于项目根目录; - 以星号
*通配多个字符,即匹配多个任意字符;使用两个星号**表示匹配任意中间目录,比如a/**/z可以匹配a/z,a/b/z或a/b/c/z等; - 以问号
?通配单个字符,即匹配一个任意字符; - 以方括号
[]包含单个字符的匹配列表,即匹配任何一个列在方括号中的字符。比如[abc]表示要么匹配一个a,要么匹配一个b,要么匹配一个c;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配。比如[0-9]表示匹配所有0到9的数字,[a-z]表示匹配任意的小写字母; - 以叹号
!表示不忽略(跟踪)匹配到的文件或目录,即要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号!取反。需要特别注意的是:如果文件的父目录已经被前面的规则排除掉了,那么对这个文件用!规则是不起作用的。也就是说!开头的模式表示否定,该文件将会再次被包含,如果排除了该文件的父级目录,则使用!也不会再次被包含。可以使用反斜杠进行转义。
使用示例:
# 忽略所有临时和备份文件
*.tmp
*.swp
*~
# 忽略 Python 项目常见文件
__pycache__/
*.pyc
.env
# 忽略前端项目常见文件
dist/
build/
node_modules/
npm-debug.log
yarn-error.log
# 忽略所有隐藏文件夹(.开头)
.*/
# 忽略所有.env文件,但保留.env.example
.env
!.env.example
.gitattributes
.gitattributes 文件用于定义 Git 如何处理特定文件的属性,比如文本文件的换行符、合并策略、diff 方式等。常用于跨平台开发、自动化处理等场景。通常放置在仓库的根目录下,但也可以出现在子目录中(子目录中的设置会覆盖父目录的设置)。
文件语法格式为:
<匹配模式> <属性1> <属性2> ...
文本行尾处理
text:标记文件为文本文件,Git 会对行尾进行标准化处理-text:明确禁止行尾转换eol=lf或eol=crlf:强制使用特定行尾风格
.gitattributes可以使用如下指令强制所有文本文件使用 LF 换行符:
# Windows 下使用 CRLF,其他平台使用 LF
*.sh text eol=lf
*.bat text eol=crlf
# 所有文本文件统一为 LF 换行符
* text=auto eol=lf
为什么需要关注行尾换行符呢?
原因主要是:不同操作系统的换行符不同,Linux/macOS使用LF(\n),Windows使用的是CRLF(\r\n),如果团队成员在不同操作系统下开发,换行符不统一会导致:Git 显示大量无意义的变更(仅换行符不同),合并冲突增多,代码审查困难
当统一使用LR时,Windows用户会不会因为换行出现冲突呢?
答案是不会。现在主流的编辑器(如 VSCode、Sublime Text、Notepad++、JetBrains 系列等)都能很好地识别和处理 LF 换行符,即使在 Windows 系统下也不会出现乱码或显示异常。此外,Git 提供了自动换行符转换的功能。常见配置如下:core.autocrlf=true,拉取代码时,Git 会把仓库中的 LF 自动转换为本地的 CRLF(\r\n),提交代码时,Git 会把 CRLF 转回 LF 存储到仓库。
# Windows 用户设置
git config --global core.autocrlf true
# Linux/macOS 用户设置
git config --global core.autocrlf input
比较与合并
diff:标记文件应使用文本差异算法进行比较,Git 会使用常规的行比较算法来显示文件的更改-diff:不使用文本差异算法,会告诉 Git 将文件视为二进制文件处理merge:指定合并策略merge=binary:当作二进制文件处理,告诉 Git 不要尝试自动合并该类型的文件。merge=union:使用合并双方的所有行
使用示例:
# 避免 Git 尝试对二进制文件进行行比较,可以显著提高性能
*.pdf -diff
*.png -diff
# 根据文件类型自定义差异算法
*.md diff=markdown
*.cpp diff=cpp
*.sql diff=sql
# 禁止合并二进制文件与容易产生冲突的文件
*.png -merge
*.jpg -merge
package-lock.json -merge
*.lock -merge
移除/修改语言统计
linguist-detectable 是 GitHub 的 Linguist 组件专门使用的 .gitattributes 属性,用于控制文件是否应被纳入仓库语言统计。
使用示例:
# 强制将特定文件纳入语言统计
*.mypl linguist-detectable=true
*.rpc linguist-language=Python linguist-detectable=true
# 排除实际上不是源代码的文本文件
*.txt linguist-detectable=false
CSV/*.csv linguist-detectable=false
注意事项
更改.gitattributes不会自动重新规范化现有文件,需要手动命令:
git rm --cached -r .
git reset --hard