.gitignore语法:bin vs bin/vs. bin/*vs. bin/**

cha*_*sie 84 git

什么是加入之间的区别bin,bin/,bin/*bin/**在我的.gitignore文件?我一直在使用bin/,但是看看其他 .gitignore文件(在eclipse文件中,双星和单星甚至一起使用:tmp/**/*这是怎么回事?)我看到前两个模式也被广泛使用.有人可以解释三者之间的差异吗?

Sid*_*ddy 82

bin匹配任何名为'bin'的文件目录.

bin/匹配名为'bin'的任何目录,这实际上意味着它的所有内容,因为Git不会单独跟踪目录.

bin/*直接匹配所有文件和目录bin/.这可以防止Git自动查找其子目录中的任何文件,但是如果bin/foo创建了一个子目录,则该规则将匹配foo的内容.

bin/**匹配任何bin/目录及其所有子目录中的所有文件和目录.

"any"这个词在这里至关重要,因为规则与存储库根目录无关,并且适用于文件系统树中的任何位置.您必须使用/(或!/取消忽略)开始规则,这意味着存储库的根,而不是系统的根,以便仅匹配预期的内容.

警告:你应该从来没有使用类似的规则dir/*,/dir/**独自一人,等等,除非你也未忽略的东西,这个目录中存在.省略星号,否则你可能会从某些调用中永久丢失大量数据git gc,git stash甚至更多.

我真的不知道tmp/**/*该做什么.我最初认为它可以用于匹配子目录中的文件tmp/而不是直接存在于其中的文件tmp/.但是一个简单的测试似乎表明这会忽略所有文件tmp/.

  • 只是为了澄清,`bin /`和`bin/**'有什么区别? (10认同)
  • 这个答案在很多方面都是错误的.首先,git不跟踪目录,因此.gitignore条目只能匹配目录内容,而不能匹配目录.其次,`bin`匹配****一个名为`bin`**的文件和**'bin`文件夹的内容.第三,`bin/*`**匹配**子目录中的任何文件.你们有人测试过吗? (9认同)
  • 请注意,如果你想跟踪bin /目录中的所有文件但忽略其子目录中的所有文件,你可以(在后续行上)`bin/**\n!bin/*`(因为我看不到)如何在mini-Markdown中强行换行) (3认同)

Sim*_*han 42

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
Run Code Online (Sandbox Code Playgroud)

存在以下未跟踪的文件:

$ git ls-files --other
.gitignore
dir-contents/can-reinclude
dir-only/cant-reinclude
file
ignored-file
or-dir/ignored-file
Run Code Online (Sandbox Code Playgroud)

但是您可以看到以下文件不会被忽略:

$ git ls-files --other --exclude-standard
.gitignore
dir-contents/can-reinclude
file
Run Code Online (Sandbox Code Playgroud)

如果你试图添加,你得到:

$ 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
Run Code Online (Sandbox Code Playgroud)

我认为这种行为是个错误.(这一切都在git version 1.8.4.msysgit.0)

  • "dir /"和"dir/**"的不同行为.用`!`忽略,因为"如果排除该文件的父目录,则无法重新包含文件"[[source](http://git-scm.com/docs/gitignore)] .令人困惑,但出于性能原因.请参阅[相关SO问题](http://stackoverflow.com/q/3667986). (2认同)

Tho*_*asR 22

请注意,严格来说,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
Run Code Online (Sandbox Code Playgroud)

bin/

与上面相同,但它与命名的文件不匹配bin.添加尾部/告诉git仅匹配目录.

bin/*

这忽略了

  • 文件文件夹中包含名为bin
  • 名为的文件夹的直接子文件夹的内容 bin
bin/*  # 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/
Run Code Online (Sandbox Code Playgroud)

bin/**

这忽略了

  • 的内容 bin
  • 子文件夹的内容(任何嵌套级别) bin
bin/**  # 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)
Run Code Online (Sandbox Code Playgroud)


Joe*_*ips 9

我刚做了一个新的回购并试了一些东西.这是我的结果:

新结果

git版本2.10.1.windows.1

  1. 初始化几乎空的回购.只有README文件
  2. bin目录填充几层深
    • bin.txt
    • Test.txt
    • bin/a/b/bin.txt
    • bin/a/b/Test.txt
    • bin/a/bin/bin.txt
    • bin/a/bin/Test.txt
    • bin/a/bin.txt
    • bin/a/Test.txt
    • bin/bin.txt
    • bin/Test.txt
  3. 加入bingitignore:结果
    • 在下面的一切bin目录(和深)现在被忽略
    • 根级别不被忽略(/ bin.txt和/Test.txt仍然显示)
  4. 编辑binbin/在gitignore:结果
    • 没变
  5. 编辑bin/bin/*
    • 没变
  6. 编辑bin/*bin/**
    • 没变
  7. 编辑bin/**bin/**/
    • bin/bin.txt并且bin/Test.txt不再被忽视
  8. 编辑bin/**/bin/**/*
    • bin/bin.txt然后bin/Test.txt又被忽略了

老结果

git版本:2.7.0.windows.1

  1. 初始化几乎空的回购.只有README文件
  2. bin目录填充几层深
    • bin/a/b/Test.txt
    • bin/a/bin/Test.txt
    • bin/a/Test.txt
    • bin/Test.txt
  3. 加入bingitignore:结果
    • 在下面的一切bin目录(和深)现在被忽略
  4. 编辑binbin/在gitignore:结果
    • bin目录下面(和更深层)的所有内容仍然被忽略(没有变化)
  5. 编辑bin/bin/*
    • bin目录下面(和更深层)的所有内容仍然被忽略(没有变化)
  6. 编辑bin/*bin/**
    • bin目录下面(和更深层)的所有内容仍然被忽略(没有变化)
  7. 编辑bin/**bin/**/
    • bin/Test.txt 不再被忽视
  8. 编辑bin/**/bin/**/*
    • bin目录下方(和更深层)的所有内容都会再次被忽略


Von*_*onC 8

请注意,' **' 与子目录(**/bar)结合使用时,必须更改其默认行为,因为git1.8.2发行说明现在提到:

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

例如" foo/**/bar"匹配" bar"在" foo"本身或" "的子目录中foo.


要记住的规则(以及有助于理解这些语法背后的意图差异)是:

如果排除该文件的父目录,则无法重新包含文件.


通常,如果要从忽略文件夹f的子文件夹中排除文件,您可以执行以下操作:

f/**
!f/**/
!f/a/sub/folder/someFile.txt
Run Code Online (Sandbox Code Playgroud)

那是:

  • 如果第一条规则是f/,则该文件夹f/将被忽略,下面的规则f无关紧要.
  • f/**实现相同f/,但忽略所有子元素(文件和子文件夹).
    这让你有机会到白名单(从gitignore排除)的子文件夹:!f/**/.
  • 由于不会忽略所有f子文件夹,您可以添加规则以排除文件()!f/a/sub/folder/someFile.txt


归档时间:

查看次数:

27652 次

最近记录:

7 年,11 月 前