什么是加入之间的区别bin,bin/,bin/*和bin/**在我的.gitignore文件?我一直在使用bin/,但是查看其他 .gitignore文件(在eclipse文件中,甚至将双星和单星也像这样一起使用:tmp/**/*这是怎么回事?)我看到前两种模式也得到了广泛使用。有人可以解释一下两者之间的区别吗?
什么是加入之间的区别bin,bin/,bin/*和bin/**在我的.gitignore文件?我一直在使用bin/,但是查看其他 .gitignore文件(在eclipse文件中,甚至将双星和单星也像这样一起使用:tmp/**/*这是怎么回事?)我看到前两种模式也得到了广泛使用。有人可以解释一下两者之间的区别吗?
Answers:
bin匹配任何名为“ bin”的文件或目录。
bin/匹配任何名为“ bin”的目录,这实际上意味着其所有内容,因为Git不会单独跟踪目录。
bin/*直接匹配any中的所有文件和目录bin/。这样可以防止Git自动在其子目录中查找任何文件,但是,例如,如果bin/foo创建了子目录,则此规则将与的内容不匹配foo。
bin/**匹配任何bin/目录及其所有子目录中的所有文件和目录。
这里的“ any”一词非常重要,因为规则与存储库根目录无关,并且适用于文件系统树中的任何位置。您必须以/(否则!/要忽略)规则开头,这意味着存储库的根目录,而不是系统的根目录,以便仅匹配预期的目标。
警告:你应该从来没有使用类似的规则dir/*,/dir/**独自一人,等等,除非你也未忽略的东西,这个目录中存在。省略星号,否则您可能会因的某些调用而永久丢失大量数据git gc,git stash甚至更多。
我真的不知道该怎么tmp/**/*做。最初,我认为它可以用来匹配子目录中的文件,tmp/但不能匹配直接存在于其tmp/自身中的文件。但是一个简单的测试似乎表明这会忽略中的所有文件tmp/。
bin/和之间有什么区别bin/**?
bin/将忽略bin目录,而bin/**将包括bin目录但不包含任何目录
bin/将忽略目录本身(包括所有子目录和文件),而bin/**将忽略bin目录及其子目录中的所有文件,但不忽略bin目录本身。我不确定这是否正确。
bin/** \n !bin/*(因为我看不到如何在mini-Markdown中
bin匹配两种命名文件,bin 并在内容bin文件夹中。第三,bin/* 是否匹配其子目录中的任何文件。你们都测试过了吗?
bin并且bin/仅在于后者仅与目录匹配。
bin/**/*与bin/**(根据@VonC的答案显然是从1.8.2开始)相同。
最棘手的一个,我只花了一个小时左右撕裂我的头发了,是bin/和bin/**不是很一样!由于前者会忽略整个目录,而后者会忽略其中的每个文件,并且git在几乎所有情况下都不关心目录,因此通常没有区别。但是,如果您尝试使用它!来忽略子路径,那么您会发现如果忽略父目录,则git(ahem)会忽略它!(再次,而不是目录内容)
通过示例,这是最清楚的,因此对于新设置的存储库,其设置如下:
$ cat .gitignore
ignored-file
or-dir
dir-only/
!dir-only/cant-reinclude
dir-contents/**
!dir-contents/can-reinclude
$ mkdir or-dir dir-only dir-contents
$ touch file ignored-file or-dir/ignored-file dir-only/cant-reinclude dir-contents/can-reinclude
存在以下未跟踪的文件:
$ git ls-files --other
.gitignore
dir-contents/can-reinclude
dir-only/cant-reinclude
file
ignored-file
or-dir/ignored-file
但是您可以看到以下文件未被忽略:
$ git ls-files --other --exclude-standard
.gitignore
dir-contents/can-reinclude
file
如果您尝试添加,则会得到:
$ git add dir-only/cant-reinclude
The following paths are ignored by one of your .gitignore files:
dir-only/cant-reinclude
Use -f if you really want to add them.
fatal: no files added
我认为此行为是一个错误。(全部打开git version 1.8.4.msysgit.0)
请注意,严格来说,git不跟踪目录,仅跟踪文件。它因此是不能添加一个目录,只有它的内容。
.gitignore然而,在这种情况下,git假装理解目录,其唯一原因是
如果排除了该文件的父目录,则无法重新包含该文件。
https://git-scm.com/docs/gitignore#_pattern_format
这对于排除模式意味着什么?让我们详细了解一下它们:
bin这忽略了
bin。bin您可以bin通过添加后续!条目将被忽略的文件和文件夹列入白名单,但不能将名为以下内容的文件夹的内容列入白名单。bin
bin
!bin/file_in_bin # has no effect, since bin/ is blacklisted!
!bin/* # has no effect, since bin/ is blacklisted!
!file_in_bin # has no effect, since bin/ is blacklisted!
!bin # this works
bin/除与名为的文件不匹配外,与上面相同bin。添加尾随/告诉git仅匹配目录。
bin/*这忽略了
binbinbin/* # blacklists bin/file_in_bin and bin/subfolder/
!bin/subfolder/file_in_sub # has no effect, since bin/subfolder is blacklisted!
!bin # whitelists files named bin/bin, since bin/ itself is not blacklisted
!bin/ # has no effect, since bin/ itself is not blacklisted
!bin/file_in_bin # works since bin/ itself is not blacklisted
!file_in_bin # works too
!bin/subfolder # works (so implicitly whitelists bin/subfolder/file_in_sub)
!bin/subfolder/ # works just as well
!bin/* # works for file_in_bin and subfolder/
bin/**这忽略了
binbinbin/** # blacklists bin/file_in_bin and
# bin/subfolder/ and bin/subfolder/file_in_sub and
# bin/subfolder/2/ and bin/subfolder/2/file_in_sub_2
!bin/subfolder/file_in_sub # has no effect, since bin/subfolder is blacklisted
!bin/subfolder/2/ # has no effect, since bin/subfolder is blacklisted
!bin/subfolder/2/file_in_sub_2 # has no effect, since bin/subfolder is blacklisted
!bin/subfolder # works only in combinations with other whitelist entries,
# since all contents of subfolder are blacklisted (1)
!bin/file_in_bin # works since bin itself is not blacklisted
!bin/* # works for file_in_bin and subfolder; see (1)
我刚刚做了一个新的仓库,并尝试了一些东西。这是我的结果:
git版本2.10.1.windows.1
bin目录几层
bin.txtTest.txtbin/a/b/bin.txtbin/a/b/Test.txtbin/a/bin/bin.txtbin/a/bin/Test.txtbin/a/bin.txtbin/a/Test.txtbin/bin.txtbin/Test.txtbin到gitignore:结果
bin目录(和深)现在被忽略bin为bin/:结果
bin/为bin/*
bin/*为bin/**
bin/**为bin/**/
bin/bin.txt并且bin/Test.txt不再被忽略bin/**/为bin/**/*
bin/bin.txt并bin/Test.txt再次被忽略git版本:2.7.0.windows.1
bin目录几层
bin/a/b/Test.txtbin/a/bin/Test.txtbin/a/Test.txtbin/Test.txtbin到gitignore:结果
bin目录(和深)现在被忽略bin为bin/:结果
bin目录(及更深层)下的所有内容仍将被忽略(不变)bin/为bin/*
bin目录(及更深层)下的所有内容仍将被忽略(不变)bin/*为bin/**
bin目录(及更深层)下的所有内容仍将被忽略(不变)bin/**为bin/**/
bin/Test.txt 不再被忽略bin/**/为bin/**/*
bin目录(及更深层)下的所有内容都将再次被忽略请注意,“ **”与子目录(**/bar)组合时,必须已更改其默认行为,因为git1.8.2的发行说明现在提到:
.gitignore和.gitattributes文件中的模式可以具有**/,作为与0或更高级别的子目录匹配的模式。例如,“
foo/**/bar”匹配“bar”foo本身或“foo”子目录中的“ ”。
要记住的规则(并有助于理解这些语法背后的意图差异)是:
通常,如果要从忽略文件夹f的子文件夹中排除文件,则可以执行以下操作:
f/**
!f/**/
!f/a/sub/folder/someFile.txt
那是:
f/,则该文件夹f/将被忽略,并且以下有关规则f将无关紧要。f/**与相同f/,但忽略所有子元素(文件和子文件夹)。!f/**/。f子文件夹,因此您可以添加规则以排除文件()!f/a/sub/folder/someFile.txtbin/*和之间还有另一个区别bin/。
bin/匹配foo/bin/test.txt(按预期),但bin/*不匹配,这看起来很奇怪,但已记录在案:https://git-scm.com/docs/gitignore
“ Documentation / *。html”匹配“ Documentation / git.html”,但不匹配“ Documentation / ppc / ppc.html”或“ tools / perf / Documentation / perf.html”。
其原因似乎是以下规则:
如果图案以斜杠结尾,则出于以下描述的目的而将其删除...
如果该模式不包含斜杠/,则Git会将其视为shell glob模式,并检查相对于.gitignore文件位置的路径名是否匹配…
否则,Git会将模式视为适合Fnmatch(3)使用FNM_PATHNAME标志使用的shell球…
因此,如果模式以斜杠结尾,则斜杠将被删除,并将其视为shell glob模式,在这种情况下为binmatch foo/bin/test.txt。如果以结尾/*,则不会删除斜杠,而是将其传递给fnmatch,后者在子目录中不匹配。
但是,对于foo/bin/和foo/bin/*,情况并非如此,因为即使从中删除了尾部的斜杠foo/bin/,它仍然包含斜杠,因此将其视为fnmatch模式而不是glob。即它将不匹配bar/foo/bin/test.txt