我一直在使用 git,但仍然对.gitignore文件路径感到困惑。
那么, .gitignore文件中以下两个路径有什么区别呢?
时间/* 公共/文件/**/*
我可以理解这tmp/*
将忽略其中的所有文件和文件夹。我对吗?但是第二条线路径是什么意思?
我一直在使用 git,但仍然对.gitignore文件路径感到困惑。
那么, .gitignore文件中以下两个路径有什么区别呢?
时间/* 公共/文件/**/*
我可以理解这tmp/*
将忽略其中的所有文件和文件夹。我对吗?但是第二条线路径是什么意思?
这取决于你的 shell 的行为。Git 不做任何工作来确定如何扩展这些。通常,*
匹配任何单个文件或文件夹:
/a/*/z
matches /a/b/z
matches /a/c/z
doesn't match /a/b/c/z
**
匹配任何文件夹字符串:
/a/**/z
matches /a/b/z
matches /a/b/c/z
matches /a/b/c/d/e/f/g/h/i/z
doesn't match /a/b/c/z/d.pr0n
结合**
以*
匹配整个文件夹树中的文件:
/a/**/z/*.pr0n
matches /a/b/c/z/d.pr0n
matches /a/b/z/foo.pr0n
doesn't match /a/b/z/bar.txt
今天,我找不到一台**
不能按要求工作的机器。这包括 OSX-10.11.3 (El Capitan) 和 Ubuntu-14.04.1 (Trusty)。可能是 git-ignore 已更新,或者可能是人们期望的最近的fnmatch句柄。**
因此,现在接受的答案在实践中似乎是正确的。
git中**
没有特殊含义。这是 bash >= 4.0 的一个特性,通过
shopt -s globstar
但是git不使用bash。要查看gitgit add -nv
实际执行的操作,您可以在多个级别的子目录中尝试和文件。
对于 OP,我已经尝试了所有我能想到的.gitignore
文件组合,没有比这更好的了:
public/documents/
以下内容并不像每个人都认为的那样:
public/documents/**/*.obj
无论我尝试什么,我都无法让它工作,但至少这与git docs是一致的。我怀疑当人们将它添加到 时.gitignore
,它会意外工作,只是因为他们的.obj
文件恰好是一个子目录深。他们可能从 bash 脚本中复制了双星号。但也许有些系统fnmatch(3)
可以像 bash 一样处理双星号。
如果您使用的是 Bash 4 等 shell,那么 ** 本质上是 * 的递归版本,它将匹配任意数量的子目录。
如果您为示例添加文件扩展名,这将更有意义。要在 tmp 中立即匹配日志文件,您可以键入:
/tmp/*.log
要匹配 tmp 的任何子目录中任何位置的日志文件,您可以键入:
/tmp/**/*.log
但是使用 git 版本 1.6.0.4 和 bash 版本 3.2.17(1)-release 进行测试,似乎 git 根本不支持 ** glob。gitignore的最新手册页也没有提到 **,因此这要么是 (1) 非常新,(2) 不受支持,要么 (3) 在某种程度上取决于您的系统对 globbing 的实现。
此外,您的示例中还有一些微妙的地方。这个表达式:
tmp/*
...实际上意味着“忽略 tmp 目录中的任何文件,源树中的任何位置,但不要忽略 tmp 目录本身”。在正常情况下,您可能只会写:
/tmp
...这将忽略单个顶级 tmp 目录。如果您确实需要保留 tmp 目录,同时忽略它们的内容,您应该在每个 tmp 目录中放置一个空的 .gitignore 文件,以确保 git 实际创建该目录。
请注意,当与子目录( ) 结合使用时,' **
'必须已从其默认行为更改,因为git1.8.2 的发行说明现在提到:**/bar
.gitignore
和.gitattributes
文件中的模式可以有**/
, 作为匹配 0 级或更多级别的子目录的模式。例如,“
foo/**/bar
”匹配“bar
”foo
本身或“”的子目录中的“foo
”。
请参阅提交 4c251e5cb5c245ee3bb98c7cedbe944df93e45f4:
“
foo/**/bar
”匹配“foo/x/bar
”、“foo/x/y/bar
”……但不匹配“foo/bar
”。
我们做一个特殊情况,当foo/**/
检测到(并且“foo/
”部分已经匹配)时,尝试将“bar
”与字符串的其余部分匹配。“匹配一个或多个目录”语义可以使用“
foo/*/**/bar
”轻松实现。这也使得“
**/foo
匹配”foo
除了“x/foo
”,“x/y/foo
”..签字人:Nguyễn Thái Ngọc Duy
<pclouds@gmail.com>
当前文档(
.gitignore
手册页)非常清楚不需要子目录,x/**
匹配下的所有文件(可能为空)x
.gitignore
手册页确实提到:
尾随的 "
/**
" 匹配里面的所有内容。例如,“abc/**
”匹配目录“abc
”内的所有文件,相对于.gitignore
文件的位置,具有无限深度。斜杠后跟两个连续的星号,然后斜杠匹配零个或多个目录。例如,“
a/**/b
”匹配“a/b
”、“a/x/b
”、“a/x/y/b
”等。
当不支持**时,“/”本质上是通配符的终止字符,所以当你有类似的东西时:
public/documents/**/*
它本质上是在斜线之间寻找两个通配符项目,而不是自己拿起斜线。因此,这将与以下内容相同:
public/documents/*/*
它对我不起作用,但您可以.gitignore
在该子目录中创建一个新的:
tmp/**/*.log
可以替换为.gitignore
in tmp
:
*.log