gitignore排除规则如何实际运作?

时间:2010-06-08 22:46:53

标签: git gitignore

我正在尝试解决大型目录结构上的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

但问题是,最终在/ b / c下会有其他子目录,我不想将每个单独的.gitignore放到每一个 - 我希望创建'基于项目'.gitignore文件,可以位于每个项目的顶层目录中,并覆盖所有“标准”子目录结构。

这似乎也是等同的:

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

这可能是我能够实现的最接近“工作”的东西,但是需要说明完整的相对路径和显式异常,如果我有很多名为'foo'的文件,那将会很痛苦在子目录树的不同级别。

无论如何,要么我不太明白排除规则是如何工作的,要么当目录(而不是通配符)被忽略时它们根本不起作用 - 以/

结尾的规则

任何人都可以对此有所了解吗?

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

我正在使用Cygwin / bash3上的git-1.6.6.1和Ubuntu / bash3上的git-1.7.1进行观察。

5 个答案:

答案 0 :(得分:139)

/a/b/c/*
!foo

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

将排除视为“但不是这一个”,而不是“但包含此” - “忽略此目录(/a/b/c/),但不会忽略此目录(foo)”很有意义; “忽略此目录中的所有文件(/a/b/c/*),但不忽略此目录(foo)”。引用手册页:

  

可选前缀!否定了这种模式;之前模式排除的任何匹配文件将再次包含在内。

即,文件必须已被排除,以便再次包括在内。希望能有所启发。

答案 1 :(得分:24)

我有类似的情况,我的解决方案是使用:

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

如果我正确读取**,那应该适用于任意数量的中间目录。

答案 2 :(得分:6)

这是另一种选择:

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

这会忽略每个文件和目录,除了文件/目录中的三个级别。

答案 3 :(得分:4)

这一点在.gitignore手册页中肯定不清楚。这有效:

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

# don't forget this one
!.gitignore

正如Chris所提到的,如果排除目录,则甚至不打开目录。因此,如果您希望能够忽略*但某些文件,则必须按上述方式构建这些文件的路径。对我来说这很方便,因为我想对一个库的一个文件进行代码审查,如果我想稍后再做一次,我只需添加它,其他一切都被忽略。

答案 4 :(得分:4)

更一般地说, git1.8.2 将包含来自patchin its v4prompted by some Stack Overflow questionAdam Spiers)关于确定哪个gitignore规则实际上忽略了您的文件。

请参阅git1.8.2 release notes和SO问题“which gitignore rule is ignoring my file”:
这将是命令git check-ignore