gitignore排除规则实际上是如何工作的?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (35)

我正在试图解决一个大型目录结构上的gitignore问题,但为了简化我的问题,我将其简化如下。

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

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

显然,“git状态-u”显示:

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

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

因此,如果我创建一个.gitignore:

c/

然后,“git状态-u”显示foo和bar都被忽略:

# Untracked files:
...
#       .gitignore

正如我所期望的。

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

c/
!foo

根据Ggitignore的命令,我希望这能起作用。但它没有-它仍然忽略了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--我希望创建“基于项目的”.gitignore文件,它可以位于每个项目的顶部目录中,并覆盖所有的“标准”子目录结构。

这似乎也相当于:

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

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

无论如何,我不太明白排除规则是如何工作的,或者当目录(而不是通配符)被忽略时,它们根本不工作--被以/结尾的规则结束。

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

我在Cygwin/bash 3上使用git-1.6.6.1,在Ubuntu/bash 3上使用git-1.7.1。

提问于
用户回答回答于
/a/b/c/*
!foo

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

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

一个可选前缀!,它否定该模式;任何被前一个模式排除的匹配文件都将再次包括在内。

档案已经被排除在外了。

用户回答回答于

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

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

如果我读取任意数量的中间目录,这应该是可行的。**没错。

扫码关注云+社区