Git gitignore 技术细节

官方原文地址 gitignore

gitignore 指定了 Git 追踪时应忽略的文件。 已被 Git 追踪的文件不受影响

git 会读取多个配置,并综合起来决定最后需要忽略哪些文件。

git ignore 优先级

读取的 ignore 按照以下优先级进行应用

  • 从支持的命令行中读取应用(如 git ls-files 和 git read-tree 命令,支持选项指定使用的 gitignore 模式)
  • 查找文件所在目录的 .gitignore 及其父文件夹的.gitignore 文件,直到工作目录的根目录
  • 从 $GIT_DIR/info/exclude 中读取($GIT_DIR 通常为工作目录根目录的 .git 目录)
  • 从 git 从配置文件中 core.excludesFile 配置读取到的值(该配置的位置或查找规则按照 git 配置文件的查找规则和优先级进行确定)

.gitignore 匹配规则

  • 空号不进行任何匹配,因此可以用添加空行来对规则进行分块
  • 以 # 开头的一行为注释( # 必须是第一个字符,前面不能有空格)
  • 除非进行转义,否则行末的空格会被忽略
  • ! 表示否定,用于将前面已经添加忽略的文件或目录重新纳入 git 版本跟踪。但如果文件父目录已经被排除跟踪了,! 无法生效。如果文件名中存在以 ! 开头的文件需要在gitignore中被排除,需要使用 ! 来对 ! 进行转义
  • / 用作目录的分隔符,当 / 出现在开头或中间(或都存在)时,只能从 .gitignore 文件所在目录开始匹配,如果 / 出现在末尾,则只能匹配目录
    • 匹配除 / 外的任意多个任意字符,? 匹配除 / 外的一个字符
  • / 表示在所有目录中匹配,/ 表示匹配目录下的所有文件, /**/ 表示匹配零个或多个目录

示例

示例文件结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.
├── .gitignore
├── a
│ ├── a
│ │ ├── a.txt
│ │ └── b
│ ├── a.txt
│ ├── a1.txt
│ └── b
├── a.txt
└── b
├── a
│ ├── a
│ │ ├── a.txt
│ │ └── b
│ ├── a.txt
│ ├── a1.txt
│ └── b
└── b
  • a/ - 忽略 a/ 下的所有文件和 b/a 下的所有文件(满足/在末尾,匹配任意位置的a目录下的所有文件)
  • /a - 忽略 a/ 下的所有文件,b 目录中文件不受影响(满足 / 在开头,会从根目录进行完全匹配)
  • a/b - 忽略掉了 a/b 文件,b/a/b 文件不受影响(满足 / 在中间,会从根目录进行完全匹配)
  • *.txt - 忽略掉了所有的 a.txt 和 a1.txt 文件(满足 * 可以匹配多个字符)
  • ?.txt - 忽略掉了所有的 a.txt 文件, a1.txt 文件不受影响(满足?可以匹配一个字符)
  • */b - 忽略掉了a/b 和 b/b 文件(满足*匹配了除/外的任意个字符)
  • **/b - 忽略掉了 b 目录、a/b 文件及 a/a/b 文件(满足**)