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

发布于 2025-01-21 12:27:31 字数 1891 浏览 4 评论 0 原文

我正在尝试在大型目录结构上解决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 文件,该文件忽略了A/B/C内的所有内容,但并不忽略文件 foo

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

c/

然后:a git状态-U 同时显示 foo bar bar ,如下所忽略:

# Untracked files:
...
#       .gitignore

正如我所期望的那样。

现在,如果我为 foo 添加了一个排除规则,因此:

c/
!foo

根据Gitignore manpage,我希望这能起作用。但事实并非如此 - 它仍然忽略 foo

# Untracked files:
...
#       .gitignore

这也不起作用:

c/
!a/b/c/foo

这也不是这样:

c/*
!foo

gives:

# 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使用明智的东西,例如正则表达式,而不是基于笨拙的壳语法?

我在cygwin/bash3上使用git-1.6.6.1和ubuntu/bash3上的git-1.7.1观察并观察它。

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.

I have the following directory structure of two files (foo, bar) in a brand new git repository (no commits so far):

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

Obviously, a git status -u shows:

# 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.

If I create a .gitignore thus:

c/

Then a git status -u shows both foo and bar as ignored:

# Untracked files:
...
#       .gitignore

Which is as I expect.

Now if I add an exclusion rule for foo, thus:

c/
!foo

According to the gitignore manpage, I'd expect this to to work. But it doesn't - it still ignores 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.

The order of the rules in .gitignore doesn't seem to matter either.

This also doesn't do what I'd expect:

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

That one ignores both foo and bar.

One situation that does work is if I create the file a/b/c/.gitignore and put in there:

*
!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.

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.

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?

I'm using and observe this with git-1.6.6.1 on Cygwin/bash3 and git-1.7.1 on Ubuntu/bash3.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

眼角的笑意。 2025-01-28 12:27:31
/a/b/c/*
!foo

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

认为排除在于说“但不是这个”而不是“包括” - “忽略此目录(/a/a/b/c/c/code>),但不是这个目录( foo < foo < /code>)“没有多大意义; “忽略此目录中的所有文件(/a/a/b/c/*),但不是这个( foo )”。引用男人页面:

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

即,必须将 file 再次排除在内。希望能散发出一些光线。

/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).

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:

An optional prefix ! which negates the pattern; any matching file excluded by a previous pattern will become included again.

i.e., the file has to have been excluded already to be included again. Hope that sheds some light.

画离情绘悲伤 2025-01-28 12:27:31

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

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

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

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.

不知所踪 2025-01-28 12:27:31

这是另一个选择:

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

它将忽略每个文件和目录,但文件/目录在a内深处的三个级别。

Here is another option:

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

That would ignore every file and directory, except files/directories three levels deep within a.

被你宠の有点坏 2025-01-28 12:27:31

从.Gitignore Man页面上肯定不清楚。这起作用:

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

# don't forget this one
!.gitignore

如克里斯所述,如果排除该目录,目录甚至没有打开。因此,如果您想忽略 *但某些文件,则必须如上所述构建这些文件的路径。对我来说,这很方便,因为我想对库的1个文件进行代码审查,如果我想稍后再做一次,我只会添加它,而所有其他都将被忽略。

this is definitely not clear from the .gitignore man page. This works:

*
!/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.

岁月无声 2025-01-28 12:27:31

从更一般的角度来看, git1.8.2 将包括 patch (也在其v4 中,在某些堆栈溢出问题的提示)来自 adam spiers 关于确定哪个 gitignore gitignore < /代码>规则实际上忽略了您的文件。

参见 git1.8.2发行说明和这样的问题和这样的问题“ gitignore规则是忽略我的文件
那将是命令 git check-ignore

On a more general note, git1.8.2 will include the patch (also in its v4, prompted by some Stack Overflow question) from Adam Spiers about determining which gitignore rule actually ignores your file.

See git1.8.2 release notes and the SO question "which gitignore rule is ignoring my file":
that will be the command git check-ignore.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文