吉蒂诺尔排除规则实际上是如何工作的?

我试图解决一个大型目录结构上的 gitignore 问题,但为了简化我的问题,我将它简化为以下内容。

我在一个全新的 git 存储库中有两个文件(foo,bar)的目录结构(到目前为止还没有提交) :

a/b/c/foo
a/b/c/bar

显然,“ git status-u”显示:

# Untracked files:
...
#       a/b/c/bar
#       a/b/c/foo

我要做的是创建一个。Gitignore 文件,忽略/b/c 中的所有内容,但不忽略文件‘ foo’。

如果我这样创建一个. gitignore:

c/

然后,一个“ git status-u”同时显示被忽略的 foo 和 bar:

# Untracked files:
...
#       .gitignore

正如我所料。

现在,如果我为 foo 添加一个排除规则,那么:

c/
!foo

根据 gitignore 的页面,我希望这个方法能够奏效,但是它并没有奏效——它仍然忽略了 foo:

# Untracked files:
...
#       .gitignore

这也行不通:

c/
!a/b/c/foo

这一点也是如此:

c/*
!foo

给予:

# Untracked files:
...
#       .gitignore
#       a/b/c/bar
#       a/b/c/foo

在这种情况下,尽管 foo 不再被忽略,bar 也不会被忽略。

规则的顺序在.gitignore 似乎并不重要。

这也没有达到我预期的效果:

a/b/c/
!a/b/c/foo

那个同时忽略了 foo 和 bar。

有一种情况确实可行,那就是如果我创建文件 a/b/c/. gitignore 并放入其中:

*
!foo

但问题是,最终在 a/b/c 下还会有其他子目录,我不想把它们分开。我希望创建“基于项目的”。Gitignore 文件,它们可以位于每个项目的顶部目录中,并且覆盖所有的“标准”子目录结构。

这似乎也是等价的:

a/b/c/*
!a/b/c/foo

这可能是我能做到的最接近于“工作”的事情,但是需要说明完整的相对路径和明确的异常,如果在子目录树的不同级别中有大量名为“ foo”的文件,这将是一件痛苦的事情。

无论如何,要么我不太理解排除规则是如何工作的,要么当目录(而不是通配符)被忽略时——被以/结尾的规则忽略时,排除规则根本不起作用

有人能解释一下吗?

有没有办法让 gitignore 使用正则表达式之类的合理的东西,而不是这种笨拙的基于 shell 的语法?

我在 Cygwin/bash3上使用 git-1.6.6.1,在 Ubuntu/bash3上使用 git-1.7。

87146 次浏览
/a/b/c/*
!foo

似乎对我有用(Linux 上的 git 1.7.0.4)。*非常重要,否则您将忽略目录本身(因此 git 不会查看内部) ,而忽略目录中的文件(这允许排除)。

可以将排除语句看作是“但不包括这个”而不是“但包括这个”——“忽略这个目录(/a/b/c/)但不包括这个目录(foo)”没有多大意义; “忽略这个目录(/a/b/c/*)但不包括这个目录(foo)中的所有文件”有多大意义。引用手册页:

一个可选的前缀!否定模式; 被前一个模式排除的任何匹配文件将再次包含。

也就是说,文件必须已经被排除在外才能再次被纳入。希望这能给我们一些启示。

这在.gitignore 手册页面上显然是不清楚的。这是可行的:

*
!/a
!/a/b
!/a/b/c
!/a/b/c/foo


# don't forget this one
!.gitignore

正如 Chris 所提到的,如果目录被排除在外,它甚至不会被打开。因此,如果你想能够忽略 * 但一些文件,你必须建立这些文件的路径,如上所述。对我来说这很方便,因为我想对一个库的一个文件做一个代码检查,如果我想稍后再做一个,我只需要添加它,其他的都被忽略了。

还有一个选择:

*
!/a*
!/a/*
!/a/*/*
!/a/*/*/*

这将忽略每个文件和目录,除了文件/目录。

我也有类似的情况,我的解决办法是:

/a/**/*
!/a/**/foo

如果我正确读取 **,那么对于任意数量的中间目录应该可以使用这种方法。

更一般的说明是,Git1.8.2将包括 Adam Spiers中的 补丁(也是 在它的 V4引擎里由堆栈溢出问题提示) ,用于确定哪个 gitignore规则实际上忽略了您的文件。

参见 Git1.8.2版本说明和 SO 问题“ 哪条规则忽略了我的档案”:
这将是命令 强 > git check-ignore