解释gitignore模式匹配 [英] explain gitignore pattern matching

查看:105
本文介绍了解释gitignore模式匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下目录树:

 > #pwd是回购
>树-a

├──.git
│| .....
├──.gitignore
├──README.md
├──f1.html
├──f2.html ...还有一些html
├──图片
│└──river.jpg
>

我的 .gitignore

 > cat .gitignore 
*
!*。html
!images /*.*
>

我希望images目录中的所有文件都包含在回购中。但是这并没有发生。我在gitignore中使用了以下内容:

  * 
!*。html
!images *
!*。jp * g

这里发生了什么?有没有一种测试gitignore的万无一失的方法。我查阅了文档。这里是它不理解的地方(这是在模式格式标题下):


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


解决方案首先,您问题中棘手的部分是 .gitignore file:

  * //说明排除存储库中的每个文件, 
//除非我指定!模式显式考虑它

首先,我们将考虑您的的第一个版本。 gitignore
$ b


  1. * 排除储存库中的每个文件。

  2. !*。html 允许所有html文件。 / code>考虑文件夹中所有类型的文件。

要包含所有JPG / JPEG,您可以简单地添加!*。jp * g 在第三行,这会让git考虑所有jpg和jpeg,而不管文件所在的文件夹是什么。但是你特别想从图像文件夹,而不仅仅是JPG文件,图像文件夹中的任何类型的文件。让我们来阅读一些与它相关的文档,在第3节中我们将会介绍解决方案部分。






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


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


    foo / 将匹配目录foo和路径但不会
    匹配常规文件或符号链接foo


    但还要注意,如果任何模式匹配git不考虑它。


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


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



  3. 带斜杠和特殊字符的模式(* /?):如果模式像第一个示例你给了, images /*.*它按照文档中的规定工作


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








解决方案



考虑到第三点git应考虑images目录中的所有文件!images /*.* pattern。但它并没有这样做,因为文档中提到了一个更重要的问题:
$ b


Git没有列出排除的目录


由于第一行 * ,images目录本身被忽略。所以首先我们应该告诉git考虑图像目录,后面的附加行明确地说明考虑其他类型(如果需要的话)。

  * 
!*。html
!images / //< - 考虑图片文件夹
!images /*.*
$ b

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

I have the following directory tree:

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

I also have the following in my .gitignore:

> cat .gitignore
*
!*.html
!images/*.*
>

I would like all files in the images directory to be included in the repo. But that is not happening. I got it to work using the following in gitignore:

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

What is happening here? Is there a foolproof way to test gitignore. I checked the documentation. Here is the point it don't understand (this is under pattern format heading):

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".

解决方案

Firstly the tricky part in your question is the first line in the .gitignore file:

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

First we will consider the first version of your .gitignore.

  1. * exclude every file in the repository.
  2. !*.html allow all html files.
  3. !images/*.* consider all types of file in images folder.

To include all JPG/JPEG you could have simply added !*.jp*g at 3rd line, which would have made git to consider all jpg and jpeg irrespective of any folder where that file is. But you specifically wanted only from images folder and not only jpg, any type of file in the images folder. Let's read some documentation related to it and in 3rd section we will go to solution part.


Git ignore pattern regarding the folder consideration:

  1. Pattern ending only with slash: If a pattern ends with <dir-name>/ then git will ignore the files contained in that directory and all other sub-directories. As example given in the docs

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

    but also note, if any pattern matches a file in the excluded directory, git doesn’t consider it.

  2. Pattern does not have slash: If you are specifying the dir name in the ignore list which does not end with a slash, git will consider it as just a pattern, which can match any file having that pathname.

    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. Pattern with slash and special character (*/?) : If the pattern ends like the 1st example you gave, images/*.* It works as specified in the documentation

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


Solution

Considering 3rd point git should consider all the files in the images directory for !images/*.* pattern. But it is not doing that because the documentation says one more important point

Git doesn’t list excluded directories

Because of the first line * the "images" directory itself is ignored. So first we should tell the git to consider images directory and later additional lines explicitly to say consider the other types (if needed).

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

Note : the last line considers all types of files only from images directory not from any of its sub-directories. (3rd point in section 2)

这篇关于解释gitignore模式匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆