解释 gitignore 模式匹配

explain gitignore pattern matching

我有以下目录树:

> #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。我检查了 documentation。这是它不明白的地方(这是在 模式格式 标题下):

Otherwise, Git treats the pattern as a shell glob suitable for consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will not match a / in the pathname. For example, "Documentation/*.html" matches "Documentation/git.html" but not "Documentation/ppc/ppc.html" or "tools/perf/Documentation/perf.html".

首先,您问题中棘手的部分是 .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,图像文件夹中的任何类型的文件。让我们阅读一些相关的文档,在第 3 部分我们将转到解决方案部分。


Git 忽略有关文件夹注意事项的模式:

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

    foo/ will match a directory foo and paths underneath it, but will not match a regular file or a symbolic link foo

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

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

    If the pattern does not contain a slash /, Git treats it as a shell glob pattern and checks for a match against the pathname relative to the location

  3. 带斜杠和特殊字符的模式 (*/?) :如果模式像您给出的第一个示例那样结束,images/*.* 它有效如文档中所述

    Example: "Documentation/*.html" matches "Documentation/git.html" but not "Documentation/ppc/ppc.html" or "tools/perf/Documentation/perf.html".


解决方案

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

Git doesn’t list excluded directories

由于第一行 *,"images" 目录本身被忽略。因此,首先我们应该告诉 git 考虑图像目录,然后在其他行中明确说明考虑其他类型(如果需要)。

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

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