解释 gitignore 模式匹配

问题描述 投票:0回答:1

我有以下目录树:

> #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/*.*
>

我希望图像目录中的所有文件都包含在存储库中。但这并没有发生。我在 gitignore 中使用以下命令让它工作:

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

这里发生了什么?有没有一种万无一失的方法来测试 gitignore.我检查了文档。这是它不理解的一点(这是在 pattern format 标题下):

否则,Git 会将模式视为适用于的 shell glob fnmatch(3) 与 FNM_PATHNAME 标志的消耗:通配符 模式将与路径名中的 / 不匹配。例如, “Documentation/*.html”与“Documentation/git.html”匹配,但不匹配 “Documentation/ppc/ppc.html”或“tools/perf/Documentation/perf.html”。

regex git gitignore
1个回答
58
投票

首先,你的问题中棘手的部分是

.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/*.*
    考虑图像文件夹中所有类型的文件。

要包含所有 JPG/JPEG,您可以简单地在第 3 行添加

!*.jp*g
,这将使 git 考虑所有 jpg 和 jpeg,而不管该文件所在的任何文件夹。但您特别想要仅来自图像文件夹,而不仅仅是 jpg,图像文件夹中的任何类型的文件。让我们阅读一些与之相关的文档,在第三部分我们将转到解决方案部分。


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

  1. 仅以斜杠结尾的模式:如果模式以

    <dir-name>/
    结尾,那么 git 将忽略该目录和所有其他子目录中包含的文件。作为文档中给出的示例

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

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

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

    如果模式不包含斜杠 /,Git 将其视为 shell glob 模式 并检查相对于路径名的匹配 地点

  3. 带有斜杠和特殊字符 (*/?) 的模式:如果模式像您给出的第一个示例一样结束,

    images/*.*
    它按照文档中指定的方式工作

    示例:“Documentation/*.html”与“Documentation/git.html”匹配,但不匹配 “Documentation/ppc/ppc.html”或“tools/perf/Documentation/perf.html”。


解决方案

考虑到第三点,git 应该考虑图像目录中的所有文件的

!images/*.*
模式。但它并没有这样做,因为文档说了更重要的一点

Git 不列出排除的目录

由于第一行

*
“images”目录本身被忽略。因此,首先我们应该告诉 git 考虑图像目录,然后明确地告诉 git 考虑其他类型(如果需要)。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.