/dir
Git 存储库中/dir/
的 .gitignore 文件之间有区别吗?
以下有何不同?
/dir
/dir/
/dir/*
这是一个老问题,但在 Google 上排名靠前且投票最多的答案是错误的。正确答案来了。
是的,这些规则是不同的。
/dir
将匹配文件、目录、链接、任何命名的东西dir
/dir/
将只匹配一个名为dir
/dir/*
dir
将匹配一个名为(但不是dir
目录本身)的目录中的所有文件、目录和任何其他内容。/dir
,/dir/
并且/dir/*
不等价。使用覆盖规则时差异非常明显,例如著名!.gitkeep
的绕过跟踪空目录的限制。假设文件存在dir/.gitkeep
/dir
and /dir/
,Git 甚至不会查看目录内部,因此.gitkeep
不会看到。/dir/*
,Git 将检测到该文件,如果.gitkeep
提交,该目录将被保留,因为该规则不适用于目录本身,仅适用于其内容。观察:上面提到的所有规则都锚定在当前目录(所在的地方.gitignore
),因为/
前缀。如果没有前缀,则规则不仅适用于该特定目录,而且适用于子目录或存储库中的任何位置,如果.gitignore
位于根级别。
根据gitignore(5)的模式格式部分:
如果模式以斜线结尾,则出于以下描述的目的将其删除,但它只会找到与目录的匹配项。换句话说, foo/ 将匹配目录 foo 和它下面的路径,但不会匹配常规文件或符号链接 foo(这与 pathspec 在 git 中的一般工作方式一致)。
如果模式不包含斜杠 /,git 将其视为 shell glob 模式并检查相对于 .gitignore 文件位置的路径名是否匹配(如果不是来自 .gitignore,则相对于工作树的顶层文件)。
这意味着“dir”可以是文件、目录或符号链接,但带有斜杠的“dir/”只会匹配目录。在大多数情况下,差异并不重要,但是当它发生时,理解差异可以消除 .gitignore 文件中的歧义。
Git 2.23(2019 年第三季度)尝试修改 gitignore 模式中关于斜杠的描述(用于表示“仅锚定到此级别”和“仅匹配目录”等内容)
该文档现在包括:
斜杠 '
/
' 用作目录分隔符。
分隔符可能出现在.gitignore
搜索模式的开头、中间或结尾。如果在模式的开头或中间(或两者)有分隔符,则该模式是相对于特定
.gitignore
文件本身的目录级别的。
否则,模式也可能在低于该.gitignore
级别的任何级别匹配。如果模式末尾有分隔符,则该模式将仅匹配目录,否则该模式可以匹配文件和目录。
例如,模式
doc/frotz/
匹配doc/frotz
目录,但不匹配a/doc/frotz
目录;
但是frotz/
匹配frotz
,a/frotz
这是一个目录(所有路径都是.gitignore
文件的相对路径)。星号“
*
”匹配除斜线以外的任何内容。
字符 "?
" 匹配除 "/
" 之外的任何一个字符。
范围表示法,例如[a-zA-Z]
,可用于匹配范围内的字符之一。有关更详细的说明,
请参见 fnmatch(3) 和标志。FNM_PATHNAME