gitignore 中 * 和 /* 的区别
difference between * and /* in gitignore
我发现 /*
和 *
在比较设置时有不同的含义:
*
!/init.el
!/README.md
!.gitignore
!/lib/
VS
/*
!/init.el
!/README.md
!.gitignore
!/lib/
前者不追踪/lib/
但后者追踪
如何理解*
和/*
?
更新
我认为这个问题与另一个问题不完全相同。因为他专注于 dir/**
和 dir/*
而这个专注于 /*
和 *
。
第一个版本忽略除明确列出的文件之外的所有文件。 lib
被忽略,因为它不包含可跟踪的文件。 Git 不跟踪文件夹,因此显示为空的目录似乎会被忽略。
第二个版本忽略除明确列出的所有根级文件和目录。它 not 忽略根目录中任何可跟踪的内容和 not 。 lib
已明确列出,因此不会被忽略。它包含的任何文件都不在根级别,因此也不会被忽略。
答案有点复杂,因为 Git 的扫描算法很棘手,但归结为 *
匹配 lib/custom-file.el
但 /*
匹配不是。
作为一般规则,在 glob 模式中,*
不会 "cross" 路径名分隔符 /
-es。因此 A*B
匹配 ANameThatEndsInB
但不匹配 ADirectory/WithAFileB
.
将 /
放在 glob 模式中需要 /
之前的内容命名目录,而 /
之后的内容出现在目录中:A*/*B
匹配 ADirectory/WithAFileB
。名称组件 ADirectory
和 WithAFileB
分别与全局组件 A*
和 *B
.
匹配
ending 在 /
中的 glob 模式与在 */
中一样,仅匹配 目录。一个 starting with /
在 Git 中有另一个特殊含义(但请注意,例如 .gitignore
条目 /foo/bar/
由两个组件:/foo/
然后是 bar/
;bar/
部分 不 以斜杠开头)。特别是,如果模式以 /
开头,它仅适用于 Git 目录的顶级文件。如果那是顶层 .gitignore
那么这意味着 work-tree 本身的根。
现在,与 一样,如果 Git 在一个目录中没有现有的 tracked 文件,那么 Git 就不会有时必须阅读那个目录。与目录名称匹配的忽略模式将使 Git 跳过 目录扫描,如果 Git 由于某些其他原因尚未扫描该目录.所以一般来说,如果你有一个 .gitignore
在任何地方都有 *
,任何目录都会被完全跳过——好吧,只要 Git 不需要查看出于其他原因。因此 .gitignore
中的 *
倾向于忽略所有目录。但是,Git 的忽略规则指出,每当 Git 拥有文件或目录名称并正在检查 .gitignore
个文件时,它应该通读 整个文件 并找到 所有 匹配项,包括前面带有 !
的匹配项。这意味着,例如:
*
!*/
将告诉 Git 忽略所有内容(包括目录),但通过说 不要 忽略 */
目录来覆盖它。但是 *
将继续忽略所有文件。
如果你把它写成:
/*
!/*/
您将忽略此目录(包含 .gitignore
的目录)中的所有文件,但 Git 扫描其所有子目录。任何 sub-directory 中的所有内容,例如 foo/name
将无法匹配这些 glob 模式中的任何一个,因为 foo/name
部分有一个斜线,而 *
不能穿过它。
我发现 /*
和 *
在比较设置时有不同的含义:
*
!/init.el
!/README.md
!.gitignore
!/lib/
VS
/*
!/init.el
!/README.md
!.gitignore
!/lib/
前者不追踪/lib/
但后者追踪
如何理解*
和/*
?
更新
我认为这个问题与另一个问题不完全相同。因为他专注于 dir/**
和 dir/*
而这个专注于 /*
和 *
。
第一个版本忽略除明确列出的文件之外的所有文件。 lib
被忽略,因为它不包含可跟踪的文件。 Git 不跟踪文件夹,因此显示为空的目录似乎会被忽略。
第二个版本忽略除明确列出的所有根级文件和目录。它 not 忽略根目录中任何可跟踪的内容和 not 。 lib
已明确列出,因此不会被忽略。它包含的任何文件都不在根级别,因此也不会被忽略。
答案有点复杂,因为 Git 的扫描算法很棘手,但归结为 *
匹配 lib/custom-file.el
但 /*
匹配不是。
作为一般规则,在 glob 模式中,*
不会 "cross" 路径名分隔符 /
-es。因此 A*B
匹配 ANameThatEndsInB
但不匹配 ADirectory/WithAFileB
.
将 /
放在 glob 模式中需要 /
之前的内容命名目录,而 /
之后的内容出现在目录中:A*/*B
匹配 ADirectory/WithAFileB
。名称组件 ADirectory
和 WithAFileB
分别与全局组件 A*
和 *B
.
ending 在 /
中的 glob 模式与在 */
中一样,仅匹配 目录。一个 starting with /
在 Git 中有另一个特殊含义(但请注意,例如 .gitignore
条目 /foo/bar/
由两个组件:/foo/
然后是 bar/
;bar/
部分 不 以斜杠开头)。特别是,如果模式以 /
开头,它仅适用于 Git 目录的顶级文件。如果那是顶层 .gitignore
那么这意味着 work-tree 本身的根。
现在,与 .gitignore
在任何地方都有 *
,任何目录都会被完全跳过——好吧,只要 Git 不需要查看出于其他原因。因此 .gitignore
中的 *
倾向于忽略所有目录。但是,Git 的忽略规则指出,每当 Git 拥有文件或目录名称并正在检查 .gitignore
个文件时,它应该通读 整个文件 并找到 所有 匹配项,包括前面带有 !
的匹配项。这意味着,例如:
*
!*/
将告诉 Git 忽略所有内容(包括目录),但通过说 不要 忽略 */
目录来覆盖它。但是 *
将继续忽略所有文件。
如果你把它写成:
/*
!/*/
您将忽略此目录(包含 .gitignore
的目录)中的所有文件,但 Git 扫描其所有子目录。任何 sub-directory 中的所有内容,例如 foo/name
将无法匹配这些 glob 模式中的任何一个,因为 foo/name
部分有一个斜线,而 *
不能穿过它。