.gitignore文件中路径的差异?

时间:2009-03-25 11:59:03

标签: gitignore

我一直在使用git,但仍然对 .gitignore 文件路径感到困惑。

那么, .gitignore 文件中的以下两个路径有什么区别?

tmp/*
public/documents/**/*

我可以理解tmp/*会忽略其中的所有文件和文件夹。我对吗? 但是第二条线路的意思是什么?

6 个答案:

答案 0 :(得分:55)

这取决于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

答案 1 :(得分:15)

如果你正在使用像Bash 4这样的shell,那么**本质上是*的递归版本,它将匹配任意数量的子目录。

如果在示例中添加文件扩展名,则更有意义。要在tmp中立即匹配日志文件,请键入:

/tmp/*.log

要在tmp的任何子目录中的任何位置匹配日志文件,请键入:

/tmp/**/*.log

但是使用git版本1.6.0.4和bash版本3.2.17(1)进行测试 - 释放,似乎git根本不支持** globs。 most recent man page for gitignore也没有提到**,所以这是(1)非常新,(2)不受支持,或(3)某种程度上依赖于系统的globbing实现。

此外,您的示例中还有一些微妙的内容。这个表达式:

tmp/*

...实际上意味着“在源树中的任何地方忽略 tmp目录中的任何文件,但不要忽略tmp目录本身”。在正常情况下,你可能只写:

/tmp

...会忽略单个顶级tmp目录。如果你确实需要保留tmp目录,而忽略它们的内容,你应该在每个tmp目录中放置一个空的.gitignore文件,以确保git实际上创建了目录。

答案 2 :(得分:15)

更新(2016年3月8日)

今天,我无法找到**无效的机器。这包括OSX-10.11.3(El Capitan)和Ubuntu-14.04.1(Trusty)。可能git-ignore已更新,或者可能是最近的 fnmatch 处理**正如人们所期望的那样。所以现在接受的答案在实践中似乎是正确的。


原帖

** git 中没有特殊含义。它是bash> = 4.0的功能,通过

shopt -s globstar

git 不使用 bash 。要查看 git 实际执行的操作,您可以在多个子目录级别中试用git add -nv和文件。

对于OP,我已经尝试了我能想到的.gitignore文件的所有组合,没有比这更好的了:

  

public/documents/

以下并不是每个人都想到的事情:

  

public/documents/**/*.obj

无论我尝试什么,我都无法工作,但至少这与git docs一致。我怀疑,当人们将其添加到.gitignore时,它会偶然起作用,因为他们的.obj文件恰好是一个深度的子目录。他们可能从bash脚本中复制了双星号。但也许有些系统fnmatch(3)可以像bash那样处理双星号。

答案 3 :(得分:14)

请注意,'**',与子目录**/bar)结合使用时,必须更改其默认行为,因为{{3}现在提到:

  

.gitignore.gitattributes文件中的模式可以有**/,作为匹配0或更多级别子目录的模式。

     

E.g。 “foo/**/bar”与“bar”本身或“foo”的子目录中的“foo”匹配。


请参阅release note for git1.8.2

  

foo/**/bar”匹配“foo/x/bar”,“foo/x/y/bar”......但不匹配“foo/bar”。
  我们提出了一个特殊情况,当检测到foo/**/时(并且“foo/”部分已经匹配),请尝试将“bar”与其余字符串匹配。

     

“匹配一个或多个目录”语义可以使用“foo/*/**/bar”轻松实现。

     

除了“**/foo”,“foo”之外,这也会使“x/foo”与“x/y/foo”匹配。

     

签名:NguyễnTháiNgọcDuy<pclouds@gmail.com>


commit 4c251e5cb5c245ee3bb98c7cedbe944df93e45f4Simon Buchan

  

当前文档(commented)非常明确,不需要子目录,x/**匹配(可能为空)x下的所有文件

.gitignore手册页确实提到了:

  

尾随“/**”匹配内部的所有内容。例如,“abc/**”匹配目录“abc”内的所有文件,相对于.gitignore文件的位置,具有无限深度。

     

斜杠后跟两个连续的星号,然后斜杠匹配零个或多个目录。例如,“a/**/b”匹配“a/b”,“a/x/b”,“a/x/y/b”等等。

答案 4 :(得分:5)

当不支持**时,“/”本质上是通配符的终止字符,所以当你有类似的东西时:

public/documents/**/*

它本质上是在斜杠之间寻找两个通配符项,而不是自己获取斜杠。因此,这将与:

相同
public/documents/*/*

答案 5 :(得分:2)

它对我不起作用,但你可以在该子目录中创建一个新的.gitignore

tmp/**/*.log

可以替换为.gitignore中的tmp

*.log