git .gitignore 排除规则实际上是如何工作的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3001888/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do .gitignore exclusion rules actually work?
提问by davidA
I'm trying to solve a gitignore problem on a large directory structure, but to simplify my question I have reduced it to the following.
我正在尝试解决大型目录结构上的 gitignore 问题,但为了简化我的问题,我将其简化为以下内容。
I have the following directory structure of two files (foo, bar) in a brand new git repository (no commits so far):
我在一个全新的 git 存储库中有以下两个文件 (foo, bar) 的目录结构(到目前为止没有提交):
a/b/c/foo
a/b/c/bar
Obviously, a 'git status -u' shows:
显然,'git status -u' 显示:
# Untracked files:
...
# a/b/c/bar
# a/b/c/foo
What I want to do is create a .gitignore file that ignores everything inside a/b/c but does not ignore the file 'foo'.
我想要做的是创建一个 .gitignore 文件,该文件忽略 a/b/c 中的所有内容,但不忽略文件 'foo'。
If I create a .gitignore thus:
如果我创建一个 .gitignore :
c/
Then a 'git status -u' shows both foo and bar as ignored:
然后 'git status -u' 显示 foo 和 bar 都被忽略:
# Untracked files:
...
# .gitignore
Which is as I expect.
正如我所料。
Now if I add an exclusion rule for foo, thus:
现在,如果我为 foo 添加排除规则,则:
c/
!foo
According to the gitignore manpage, I'd expect this to to work. But it doesn't - it still ignores foo:
根据 gitignore 联机帮助页,我希望这能正常工作。但它没有 - 它仍然忽略 foo:
# Untracked files:
...
# .gitignore
This doesn't work either:
这也不起作用:
c/
!a/b/c/foo
Neither does this:
这也不行:
c/*
!foo
Gives:
给出:
# Untracked files:
...
# .gitignore
# a/b/c/bar
# a/b/c/foo
In that case, although foo is no longer ignored, bar is also not ignored.
在这种情况下,虽然 foo 不再被忽略,但 bar 也不会被忽略。
The order of the rules in .gitignore doesn't seem to matter either.
.gitignore 中的规则顺序似乎也不重要。
This also doesn't do what I'd expect:
这也不符合我的预期:
a/b/c/
!a/b/c/foo
That one ignores both foo and bar.
那个忽略了 foo 和 bar。
One situation that does work is if I create the file a/b/c/.gitignore and put in there:
一种有效的情况是,如果我创建文件 a/b/c/.gitignore 并放入其中:
*
!foo
But the problem with this is that eventually there will be other subdirectories under a/b/c and I don't want to have to put a separate .gitignore into every single one - I was hoping to create 'project-based' .gitignore files that can sit in the top directory of each project, and cover all the 'standard' subdirectory structure.
但问题在于,最终 a/b/c 下会有其他子目录,我不想将单独的 .gitignore 放入每个目录中 - 我希望创建“基于项目”的 .gitignore可以位于每个项目的顶级目录中的文件,并涵盖所有“标准”子目录结构。
This also seems to be equivalent:
这似乎也是等价的:
a/b/c/*
!a/b/c/foo
This might be the closest thing to "working" that I can achieve, but the full relative paths and explicit exceptions need to be stated, which is going to be a pain if I have a lot of files of name 'foo' in different levels of the subdirectory tree.
这可能是我可以实现的最接近“工作”的事情,但是需要说明完整的相对路径和显式异常,如果我在不同级别有很多名为“foo”的文件,这将是一件痛苦的事情的子目录树。
Anyway, either I don't quite understand how exclusion rules work, or they don't work at all when directories (rather than wildcards) are ignored - by a rule ending in a /
无论如何,要么我不太明白排除规则是如何工作的,要么当目录(而不是通配符)被忽略时它们根本不起作用 - 通过以 / 结尾的规则
Can anyone please shed some light on this?
任何人都可以对此有所了解吗?
Is there a way to make gitignore use something sensible like regular expressions instead of this clumsy shell-based syntax?
有没有办法让 gitignore 使用像正则表达式这样明智的东西,而不是这种笨拙的基于 shell 的语法?
I'm using and observe this with git-1.6.6.1 on Cygwin/bash3 and git-1.7.1 on Ubuntu/bash3.
我正在使用 Cygwin/bash3 上的 git-1.6.6.1 和 Ubuntu/bash3 上的 git-1.7.1 使用并观察这一点。
回答by Chris
/a/b/c/* !foo
Seems to work for me (git 1.7.0.4 on Linux). The *
is important as otherwise you're ignoring the directory itself (so git won't look inside) instead of the files within the directory (which allows for the exclusion).
似乎对我有用(Linux 上的 git 1.7.0.4)。这*
很重要,否则您将忽略目录本身(因此 git 不会查看内部)而不是目录中的文件(允许排除)。
Think of the exclusions as saying "but not this one" rather than "but include this" - "ignore this directory (/a/b/c/
) but not this one (foo
)" doesn't make much sense; "ignore all files in this directory (/a/b/c/*
) but not this one (foo
)" does. To quote the man page:
将排除视为说“但不是这个”而不是“但包括这个”——“忽略这个目录 ( /a/b/c/
) 但不忽略这个( foo
)”没有多大意义;“忽略此目录中的所有文件 ( /a/b/c/*
) 但不忽略此 ( foo
)” 确实如此。引用手册页:
An optional prefix ! which negates the pattern; any matching file excluded by a previous pattern will become included again.
一个可选的前缀!这否定了模式;任何被先前模式排除的匹配文件将再次包含在内。
i.e., the filehas to have been excluded already to be included again. Hope that sheds some light.
即,该文件必须已被排除才能再次包含在内。希望能有所启发。
回答by medge799
I have a similar situation, my solution was to use:
我有类似的情况,我的解决方案是使用:
/a/**/*
!/a/**/foo
That should work for an arbitrary number of intermediate directories if I read **
correctly.
如果我**
正确阅读,这应该适用于任意数量的中间目录。
回答by Peter Petrik
Here is another option:
这是另一种选择:
*
!/a*
!/a/*
!/a/*/*
!/a/*/*/*
That would ignore every file and directory, except files/directories three levels deep within a.
这将忽略每个文件和目录,除了文件/目录深层的三个级别。
回答by Peter Petrik
this is definitely not clear from the .gitignore man page. This works:
这在 .gitignore 手册页中绝对不清楚。这有效:
*
!/a
!/a/b
!/a/b/c
!/a/b/c/foo
# don't forget this one
!.gitignore
As mentioned by Chris a directory is not even opened if it is excluded. So if you want to be able to ignore * but some files, you have to build the path to those files as above. For me this is convenient, because I want to do a code review on 1 file of a library and if I want to do another later I just add it, and all else is ignored.
正如克里斯所提到的,如果排除目录,则甚至不会打开目录。因此,如果您希望能够忽略 * 但某些文件,则必须按照上述方式构建这些文件的路径。对我来说这很方便,因为我想对库的 1 个文件进行代码,如果我以后想再做一个,我只需添加它,其他所有内容都将被忽略。
回答by VonC
On a more general note, git1.8.2will include the patch(also in its v4, prompted by some Stack Overflow question) from Adam Spiersabout determining which gitignore
rule actually ignores your file.
更一般地说,git1.8.2将包含来自Adam Spiers的补丁(也在其 v4 中,由一些 Stack Overflow 问题提示)关于确定哪个规则实际上忽略了您的文件。gitignore
See git1.8.2 release notesand the SO question "which gitignore rule is ignoring my file":
that will be the command git check-ignore
.
请参阅git1.8.2 发行说明和 SO 问题“ which gitignore rule is ignoring my file”:
这将是命令git check-ignore
。