.gitignore中a /和a / *和/ **之间的区别?

时间:2017-05-24 11:43:46

标签: git gitignore

这是我的文件夹。

  • 一个
    • b
      • b1.txt
      • b2.txt
    • a1.txt
    • a2.txt
  • 的.gitignore

首先

我发现如果我想忽略文件夹a,a/a/*以及a/**都可以完成。

其次:

我想忽略文件夹a中除文件夹b之外的所有内容,唯一的方法是:

a/*
!a/b/

我不知道为什么a/**无法做到这一点?

# this way can't except folder b
a/**
!a/b/

或者您可以告诉我如何使用a/**

3 个答案:

答案 0 :(得分:4)

**匹配任意数量的目录,*只有一个目录 所以,如果你。 G。忽略/a/**/d/,然后忽略/a/b/d//a/b/c/d/ 如果你e。 G。忽略/a/*/d/,然后忽略/a/b/d/,而不忽略/a/b/c/d/

如果忽略某个文件夹,那么Git甚至不会查看其内容来检查包含内容。这就是为什么你不能忽略/a/然后包含/a/b/,因为Git甚至不会查看/a/。因此,您必须忽略/a/中包含/a/*的所有内容,然后包含/a/b/以忽略/a/中的所有内容,但/a/b/的所有内容除外。< / p>

答案 1 :(得分:1)

对于第一个近似值,Git没有&#34;做&#34;目录(&#34;文件夹&#34;)。

Gitignore文件是此规则的一个例外,但是以一种棘手的方式。

首先,Git主要是关于文件。文件被跟踪或未跟踪。当且仅当索引中的当前时,文件才会被跟踪。请注意,Git可以非常快速地读取自己的索引 ,通常比底层操作系统可以读取目录树(&#34;文件夹和子文件夹&#34;)快得多。

接下来,gitignore规则主要是关于文件,因为只有文件可以不跟踪或被跟踪。当git status表示某个目录(&#34;文件夹&#34;)未被跟踪时,这意味着中包含的一个或多个未跟踪的文件 >那个目录。 (使用git add的工作方式类似,除了&#34;抱怨&#34;,要采取的行动是&#34;复制到索引&#34;。)

为了找到未跟踪的文件,Git必须打开并读取工作树中的每个目录(或&#34;文件夹&#34;)。然而,为了让Git表现更快,Git使用了这个技巧:

  • 如果路径 P (例如aa/b)命名目录,
  • 如果没有现有的跟踪的文件,其路径 P 开头(后跟一个尾部斜杠;例如,在这种情况下,那里例如,索引中没有a/b/b1.txt且没有a/a2.txt
  • 如果路径 P 匹配&#34;忽略&#34;规则(没有取消),然后

Git完全跳过阅读目录 P 。它永远不会查看其中是否有任何未跟踪的文件。这样做是因为在Linux(和其他操作系统)中读取目录的速度相对较慢。

现在我们来到a/*a/**这样的模式,其中a当前未被忽略,或者索引中的文件的路径以{{1}开头}。为了确定a/中是否存在未跟踪且应该被抱怨的文件(如果没有被忽略)或者没有抱怨(如果被忽略),Git 必须读取目录a

读取目录a后,Git发现有两个文件aa1.txt以及一个目录a2.txt。假设ba1.txt当前未跟踪,它会扫描所有a2.txt模式以查看这些模式是否与这两个文件匹配。如果没有,Git会抱怨它们(或者将它们添加到索引中)。但是.gitignore是一个目录,所以优化开始了:

  • 索引中没有b个路径,
  • b/ba/*规则
  • 相匹配

只要没有a/**!a/b规则,Git就会忽略目录!a/b/,而不会在其中查看。无论您使用的是a/b还是*

如果索引中至少有一个跟踪文件,其名称以**开头,则优化失败。或者,如果使用a/b/!a/b覆盖忽略,则不会忽略目录本身。在任何一种情况下,Git都会读取目录!a/b/。读完目录后,Git会找到文件a/b/a/b/b1.txt。然后,它会检查这些是否符合a/b/b2.txt规则。

作为Vampire noted.gitignore匹配零个或多个目录。 (如果模式 **结尾,它也匹配那些零或多个目录中的所有文件。)为了使其具有一些与**不同的操作,所以我们可以看到差异,我们需要更多级别的子目录(我们需要强制Git读取,要么明确地忽略至少一个如a/*a/b/规则,或者跟踪其中的文件。)

(在我前一段时间的实验中,我发现!与Git中的一个或多个目录匹配的情况,而不是零或更多 .I认为这发生在路径名扩展中,例如,如果您使用**。请注意:git log -- 'a/**/file.txt'匹配的忽略规则可能与其他规则不同。)

答案 2 :(得分:0)

尝试(没有/):

a
!a/b

**用于忽略“在任何子目录中”,例如,你有

a/b1.txt
a/b/b1.txt

您可以忽略b1.txt

的所有子目录中的所有a/**/b1.txt个文件