Git:如何忽略子目录中的匹配目录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1087917/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:41:42  来源:igfitidea点击:

Git: How do I ignore matching directories in a sub directory?

gitgitignore

提问by Dane O'Connor

I have a project with the following structure:

我有一个具有以下结构的项目:

/.
  /src
    /project1
      /bin
      /obj
    /project2
      /bin
      /obj
  /tools
    /tool1
      /bin 

What can I add to my .git/info/exclude to ignore all bin/obj directories under "src"? I don't want to explicitly specify each project name.

我可以向我的 .git/info/exclude 添加什么来忽略“src”下的所有 bin/obj 目录?我不想明确指定每个项目名称。

回答by Lars Haugseth

Try adding these lines to your .gitignorefile:

尝试将这些行添加到您的.gitignore文件中:

src/*/bin
src/*/obj

回答by Drew Noakes

The accepted answer didn't work for me.

接受的答案对我不起作用。

> git --version
git version 1.7.0.2.msysgit.0

Seems that forward slashes don't work with msysgit in the .gitignorefile. This works.

似乎正斜杠不适用于.gitignore文件中的msysgit 。这有效。

*\bin
*\obj

However that will match exclude any files called binor objtoo, which isn't likely to be a problem, except for when it is. The following gets around this (and yes, a forward slash works in this case):

然而,将匹配排除名为任何文件binobj过多,这是不太可能是一个问题,除了当它。以下内容解决了这个问题(是的,在这种情况下使用正斜杠):

bin/
obj/
*.user
*.suo

This matches files at different depths in the hierarchy beneath the folder in which the .gitignorefile is placed. Note that the above didn't work when I included a prefix for a specific subfolder, so I placed this in my Sourcefolder directly.

这匹配文件所在文件夹下层次结构中不同深度的.gitignore文件。请注意,当我为特定子文件夹包含前缀时,上述内容不起作用,因此我将其Source直接放在我的文件夹中。

As a Visual Studio user (presumably the OP is too from bin/obj reference) it's also nice to exclude .userand .suofiles.

作为Visual Studio用户(大概是OP太从斌/ OBJ参考)它也是很好的排除.user.suo文件。



From the gitignore specification:

gitignore 规范

Patterns have the following format:

  • A blank line matches no files, so it can serve as a separator for readability.

  • A line starting with # serves as a comment.

  • An optional prefix ! which negates the pattern; any matching file excluded by a previous pattern will become included again. If a negated pattern matches, this will override lower precedence patterns sources.

  • If the pattern ends with a slash, it is removed for the purpose of the following description, but it would only find a match with a directory. In other words, foo/ will match a directory foo and paths underneath it, but will not match a regular file or a symbolic link foo (this is consistent with the way how pathspec works in general in git).

  • If the pattern does not contain a slash /, git treats it as a shell glob pattern and checks for a match against the pathname relative to the location of the .gitignore file (relative to the toplevel of the work tree if not from a .gitignore file).

  • Otherwise, git treats the pattern as a shell glob suitable for consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will not match a / in the pathname. For example, "Documentation/*.html" matches "Documentation/git.html" but not "Documentation/ppc/ppc.html" or "tools/perf/Documentation/perf.html".

  • A leading slash matches the beginning of the pathname. For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".

模式具有以下格式:

  • 空行不匹配任何文件,因此它可以作为可读性的分隔符。

  • 以# 开头的行用作注释。

  • 一个可选的前缀!这否定了模式;任何被先前模式排除的匹配文件将再次包含在内。如果否定模式匹配,这将覆盖优先级较低的模式源。

  • 如果模式以斜杠结尾,则出于以下描述的目的将其删除,但它只会找到与目录的匹配项。换句话说, foo/ 将匹配目录 foo 和它下面的路径,但不会匹配常规文件或符号链接 foo (这与 pathspec 通常在 git 中的工作方式一致)。

  • 如果模式不包含斜杠 /,则 git 将其视为 shell glob 模式并检查与相对于 .gitignore 文件位置的路径名的匹配(如果不是来自 .gitignore 则相对于工作树的顶层)文件)。

  • 否则,git 将模式视为适合 fnmatch(3) 使用 FNM_PATHNAME 标志的 shell glob:模式中的通配符将不匹配路径名中的 /。例如,“Documentation/*.html”匹配“Documentation/git.html”但不匹配“Documentation/ppc/ppc.html”或“tools/perf/Documentation/perf.html”。

  • 前导斜杠与路径名的开头匹配。例如,“/*.c”匹配“cat-file.c”但不匹配“mozilla-sha1/sha1.c”。

回答by CB Bailey

The most obvious way would be to add these to src/.gitignore:

最明显的方法是将这些添加到src/.gitignore

obj/
bin/

This ignores any paths that are in a directory call obj, or a directory called binfrom the src directory downwards.

这将忽略目录调用中的任何路径obj,或bin从 src 目录向下调用的目录。

Something like src/*/obj/in a top-level .gitignoremight not work if you have a jagged project hierarchy with some objand bindirectories futher down the tree.

如果您有一个参差不齐的项目层次结构,其中一些和目录位于树的下方,那么类似于src/*/obj/顶层的东西.gitignore可能无法工作。objbin

Here's quick test shell script showing the ignore rule in action:

这是快速测试 shell 脚本,显示了正在执行的忽略规则:

#!/bin/sh
mkdir src
mkdir tools

mkdir src/project1
mkdir src/project2
mkdir tools/tool1

mkdir src/project1/bin
mkdir src/project1/obj
mkdir src/project2/bin
mkdir src/project2/obj
mkdir tools/tool1/bin

touch testfile
touch src/testfile
touch tools/testfile
touch src/project1/testfile
touch src/project2/testfile
touch tools/tool1/testfile
touch src/project1/bin/testfile
touch src/project1/obj/testfile
touch src/project2/bin/testfile
touch src/project2/obj/testfile
touch tools/tool1/bin/testfile

git init

add_empty() { touch "" && git add ""; }

add_empty dummy
add_empty src/dummy
add_empty tools/dummy
add_empty src/project1/dummy
add_empty src/project2/dummy
add_empty tools/tool1/dummy

git status

printf 'obj/\nbin/\n' >src/.gitignore && git add src/.gitignore

git status

The untracked file section of the first status is:

第一个状态的未跟踪文件部分是:

# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       src/project1/bin/
#       src/project1/obj/
#       src/project1/testfile
#       src/project2/bin/
#       src/project2/obj/
#       src/project2/testfile
#       src/testfile
#       testfile
#       tools/testfile
#       tools/tool1/bin/
#       tools/tool1/testfile

And after adding the .gitignore file:

添加 .gitignore 文件后:

# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       src/project1/testfile
#       src/project2/testfile
#       src/testfile
#       testfile
#       tools/testfile
#       tools/tool1/bin/
#       tools/tool1/testfile

As a test to prove that git isn't ignoring files called objand binbut is ignoring objand bindirectories further down the hierarchy after running this script:

作为测试,证明Git是不是忽略文件叫objbin而无视objbin运行此脚本后的目录进一步下跌的层次结构:

#!/bin/sh
mkdir src/project3
touch src/project3/testfile && git add src/project3/testfile
touch src/project3/obj
touch src/project3/bin

mkdir src/subdir
mkdir src/subdir/proj
touch src/subdir/proj/testfile && git add src/subdir/proj/testfile
mkdir src/subdir/proj/obj
mkdir src/subdir/proj/bin
touch src/subdir/proj/obj/testfile
touch src/subdir/proj/bin/testfile

The new untracked files are:

新的未跟踪文件是:

# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       src/project1/testfile
#       src/project2/testfile
#       src/project3/bin
#       src/project3/obj
#       src/testfile
#       testfile
#       tools/testfile
#       tools/tool1/bin/
#       tools/tool1/testfile

回答by jenson-button-event

The confusion for me was that once added, whatever mask you put on it, the files will remain in the repository unless forcibly removed, so having added a raw, compiled visual studio solution, I had to clean the repository issuing:

令我困惑的是,一旦添加,无论您在上面放什么面具,文件都将保留在存储库中,除非被强行删除,因此添加了原始的、编译的 Visual Studio 解决方案后,我必须清理存储库,发出:

git rm --cached */obj/*
git rm --cached */lib/*
git rm --cached *.user
git rm --cached *.suo
git rm --cached *ReSharper

then, added this to .gitignore:

然后,将其添加到 .gitignore:

*/*/bin
*/*/obj
*.user
*.suo
*ReSharper*

then committed:

然后承诺:

git add .
git commit -m "removed user files and binaries from repository"

回答by Kendall Helmstetter Gelner

I believe you should be able to add

我相信你应该能够添加

src/*/bin/*

to .gitignore, and anything that matches the pattern will be ignored.

到 .gitignore,任何与模式匹配的内容都将被忽略。