我正试图解决一个大目录结构上的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
文件,忽略a/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
-我希望创建 * 基于项目的 * .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,并观察到了这一点。
5条答案
按热度按时间elcex8rz1#
似乎对我有用(Linux上的git 1.7.0.4)。
*
很重要,因为否则你会忽略目录本身(这样git就不会查看里面),而不是目录中的文件(允许排除)。将排除项看作是“但不是这个”而不是“但包括这个”-“忽略这个目录(
/a/b/c/
)但不是这个目录(foo
)”没有多大意义;“忽略此目录(/a/b/c/*
)中的所有文件,但不忽略此目录(foo
)”。一个可选的前缀!,用于否定模式;被先前模式排除的任何匹配文件将再次被包括。
也就是说,* 文件 * 必须已经被排除才能再次被包含。希望这能提供一些启示。
fdbelqdn2#
我有类似的情况,我的解决方案是用途:
如果我正确读取了
**
,那么这应该适用于任意数量的中间目录。cdmah0mi3#
这里是另一个选项:
这将忽略每个文件和目录,但不包括中三层深的文件/目录。
jfewjypa4#
这一点在.gitignore手册页中肯定是不清楚的。
正如Chris所提到的,如果目录被排除,它甚至不会被打开。所以如果你想忽略 *,但是忽略一些文件,你必须如上所述构建这些文件的路径。对我来说,这很方便,因为我想对库中的一个文件做代码评审,如果我想稍后做另一个文件,我只需要添加它,其他所有的都被忽略。
fgw7neuy5#
一般来说,git1.8.2会包含Adam Spiers中的patch(也可以是in its v4,prompted by some Stack Overflow question),用于确定哪个
gitignore
规则实际上忽略了你的文件。参见git1.8.2 release notes和销售订单问题“which gitignore rule is ignoring my file“:
这将是命令
git check-ignore
。