guide

.gitignore 模式语法全解

结合示例表格,整理 gitignore 的模式语法:注释、转义、行尾空格、否定 !、末尾斜杠、锚定、*、?、[] 通配符以及 ** 规则。

.gitignore 的每一行都是一个模式。它的语法看起来与 shell 的 glob 相似,但含义会因斜杠的位置** 的位置而大不相同。以下内容以 git 官方文档 gitignore(5) 为准,示例均在 git 2.50 中实际验证过。

空行、注释与转义

行尾空格肉眼看不见,是常见错误的根源。如果规则不起作用,请在编辑器中打开空白字符显示。还要记住,只有空格会被去除,制表符不会被去除。

末尾斜杠:只匹配目录

模式以 / 结尾时,只匹配目录build/ 会忽略名为 build 的目录及其中的所有内容,但不会忽略名为 build 的文件。反之,像 build 这样不带斜杠书写时,同名的文件和目录都会匹配。

有斜杠则位置固定

去掉末尾斜杠后,如果剩余部分的开头或中间含有 /,该模式只匹配以 .gitignore 文件所在目录为基准的路径。这通常称为锚定(anchoring)。如果没有 /,则会在 .gitignore 所在位置之下的任意深度查找名称匹配的项目。

模式匹配不匹配
debug.logdebug.log, logs/debug.log
/debug.logdebug.loglogs/debug.log
logs/debug.loglogs/debug.logapp/logs/debug.log
doc/frotz/doc/frotz/ 目录a/doc/frotz/
frotz/frotz/, a/frotz/ 目录frotz 文件

第三行尤其容易混淆。logs/debug.log 中间有斜杠,因此以根目录为基准固定,与在前面加 / 的含义相同。要匹配任意深度的 logs/debug.log,请使用 **/logs/debug.log

通配符:*, ?, [ ]

两个星号 **

** 只有与斜杠相邻时才具有特殊含义。

形式含义示例
**/foo任意深度的 foofoo, a/foo, a/b/foo
**/logs/debug.log任意深度的 logs/debug.loglogs/debug.log, app/logs/debug.log
abc/**abc 中的一切abc/x, abc/x/y (但不包括 abc 本身)
a/**/b中间有 0 个或多个目录a/b, a/x/b, a/x/y/b

在其他位置,例如 foo****bar 中的 **,其行为与普通的 * 相同,无法跨越斜杠。docs/**/*.pdf 同时匹配 docs/manual.pdfdocs/a/b/manual.pdf,因为 /**/ 也能匹配 0 个目录。

用一个小例子总结

# 构建结果(仅限根目录的 build 目录)
/build/

# 任意深度的日志文件,但保留重要日志
*.log
!important.log

# docs 下的所有 PDF
docs/**/*.pdf

# 名称以 # 开头的文件
\#scratch.md
路径结果决定规则
build/app.js已忽略/build/
src/build/app.js跟踪
logs/server.log已忽略*.log
logs/important.log跟踪!important.log
docs/api/v1.pdf已忽略docs/**/*.pdf
#scratch.md已忽略\#scratch.md

把规则和路径粘贴到生成器的模式测试标签页,即可原样重现这张表。

参考

← 上一篇该忽略什么,该提交什么