解释gitignore模式匹配

时间:2015-10-17 17:23:14

标签: regex git gitignore

我有以下目录树:

> #pwd is the repo   
> tree -a
.
├── .git
│   |.....
├── .gitignore
├── README.md
├── f1.html
├── f2.html ... and some more html
├── images
│   └── river.jpg
>

我的.gitignore

中也有以下内容:
> cat .gitignore
*
!*.html
!images/*.*
>

我希望images目录中的所有文件都包含在repo中。但那并没有发生。我在gitignore中使用以下内容开始工作:

*
!*.html
!images*
!*.jp*g

这里发生了什么?是否有一种万无一失的测试gitignore的方法。我检查了documentation。这是它不明白的一点(这是模式格式标题):

  

否则,Git将模式视为适合的shell glob   fnmatch(3)使用FNM_PATHNAME标志消耗:中的通配符   pattern与路径名中的/不匹配。例如,   "文档/ * HTML&#34。匹配" Documentation / git.html"但不是   "文档/ PPC / ppc.html"或" tools / perf / Documentation / perf.html"。

1 个答案:

答案 0 :(得分:28)

首先,您问题中棘手的部分是.gitignore文件中的第一行:

*  // Says exclude each and every file in the repository,
   // unless I specify with ! pattern explicitly to consider it

首先,我们会考虑您.gitignore的第一个版本。

  1. *排除存储库中的每个文件。
  2. !*.html允许所有html文件。
  3. !images/*.*考虑图像文件夹中的所有类型的文件。
  4. 要包含所有JPG / JPEG,你可以简单地在第3行添加!*.jp*g,这将使git考虑所有jpg和jpeg,而不管该文件所在的任何文件夹。但是你只想从images文件夹而不仅仅是jpg,images文件夹中的任何类型的文件。让我们阅读一些与之相关的文档,在第3部分,我们将进入解决方案部分。

    Git忽略关于文件夹考虑的模式:

    1. 模式仅以斜杠结尾:如果模式以<dir-name>/结尾,则git将忽略该目录和所有其他子目录中包含的文件。作为文档中给出的示例

        

      foo/将匹配目录foo及其下的路径,但不会   匹配常规文件或符号链接foo

      但请注意,如果任何模式与排除目录中的文件匹配,git不会考虑它。

    2. 模式没有斜杠:如果在忽略列表中指定dir名称并不以斜杠结尾,git会将其视为一个模式,它可以匹配任何具有该路径名的文件。

        

      如果模式不包含斜杠/,Git会将其视为shell glob pattern,并检查与路径名相对应的匹配项   位置

    3. 带斜杠和特殊字符的模式(* /?):如果模式的结尾与您给出的第一个示例相同,images/*.*它的工作方式与文档中指定的一样

        

      示例:&#34;文档/ * .html&#34;匹配&#34; Documentation / git.html&#34;但不是   &#34;文档/ PPC / ppc.html&#34;或&#34; tools / perf / Documentation / perf.html&#34;。

    4. 解决方案

      考虑第3点git应该考虑图像目录中!images/*.*模式的所有文件。但它没有这样做,因为文档说了一个更重要的观点

        

      Git没有列出排除的目录

      由于第一行*&#34;图像&#34;目录本身被忽略。所以首先我们应该告诉git考虑图像目录和后来的其他行明确地考虑其他类型(如果需要)。

      *
      !*.html
      !images/                 // <- consider images folder
      !images/*.*
      

      注意:最后一行仅考虑来自images目录的所有类型的文件,而不考虑其任何子目录。 (第2节第3点)