如何在git中忽略子文件夹/子目录?

721

我有很多项目在我的.Net解决方案中。 我想排除所有的“bin/Debug”和“bin/Release”文件夹(以及它们的内容),但仍然包括“bin” 文件夹本身和其中包含的任何dll。

.gitignore 中使用“bin/”可以忽略“Debug”和“Release”文件夹,但也会忽略“bin”文件夹中包含的任何dll。

.gitignore 文件中添加 bin/Debugbin/Release 并不会排除这些目录,除非我完全限定了被忽略的模式,如 Solution/Project/bin/Debug - 但我不想这样做,因为我需要为我的解决方案中的每个项目都包含完整的模式,并且还要为任何新添加的项目添加该模式。

有什么建议吗?


1
为什么要添加DLL?如果您正在引用第三方DLL,那么添加一个所有项目都可以引用的公共文件夹可能是有意义的。 - Paddy
7
帕迪是正确的-如果那些是第三方DLL,它们应该与您的代码分开组织。但对我来说,听起来好像你正在检入自己的生成产品,这通常不是你想要的方式。您使用git跟踪信息,该信息完全包含在代码和构建配置中。产品是产品。跟踪它们会引发问题-例如,如果您更改代码但忘记构建并检入新产品,那么怎么办? - Cascabel
我在排除子文件夹方面遇到了问题。尝试了所有方法,包括这里写的准确示例,但都没有成功。最后在文件夹模式之间添加了一行额外的空白行,这样就起作用了。也许是编码问题。我使用的是Windows系统,并将其编码为UTF8。 - RoadBump
14个回答

891

你尝试使用通配符了吗?

Solution/*/bin/Debug
Solution/*/bin/Release

从git的1.8.2版本开始,你也可以使用**通配符来匹配任意级别的子目录:

**/bin/Debug/
**/bin/Release/

13
除非存在一个带有另一个项目的子文件夹(例如Solution/Module/Project),否则它可以正常工作。因此,我现在已经添加了///bin/Debug和///*/bin/Debug(用于子文件夹)。看起来你必须为目录结构中的每个级别添加通配符子文件夹。 - Marcel
2
@Marcel:好吧,Git肯定不会忽略你没有告诉它的任何文件-它只会忽略与通配符匹配的内容,不多也不少。 - Cascabel
16
很抱歉,它并没有。 - Tuukka Mustonen
2
Visual Studio出现了与**相关的错误。现在应该已经修复了。链接 - Bogac
1
我注意到在具有多个级别的目录路径中需要使用 **/ 前缀;例如,**/wwwroot/dist/,但是在尝试匹配根目录下某个地方的路径规范时,指定 dist/ 单独工作而不需要 **/ 前缀。 - bvj
显示剩余3条评论

161

你可以在顶层使用 .gitignore 来忽略项目中所有同名目录。例如:

Debug/
Release/

这应该立即更新,以便在执行git status时可见。确保这些目录尚未添加到git中,因为这将覆盖忽略。


可以通过将模式添加到操作员的 $GIT_DIR/.git/info/exclude 文件中来完成相同的操作。 - Tim Henigan
2
区别在于.gitignore文件将跟随代码并应用到任何地方。而排除文件仅针对您的存储库本地,这意味着它仅适用于特定存储库。除非其他提交者有理由想要提交这些目录,否则我建议使用.gitignore。 - Andreas
1
另一个问题是,如果您的解决方案中有一个名为“Debug”的项目,则该项目也将被忽略。我认为解决方案是所有答案和评论的结合体——重新构造解决方案以将常见或引用的dll放在不同的文件夹中,然后忽略“bin /”和/或使用通配符。 - Marcel
39
针对确保目录未被添加到 Git 的评论,给一个赞。如果该目录已经被添加到 Git 中,则执行以下操作:git rm -rf 目录名称/ - levibostian
2
对我不起作用。构建创建的目录继续出现为未暂存状态,让我发疯了。git rm -rf 报告 foo/ 指出 foo 不存在。 - Lewis Levin
奇怪,我无法重现那种行为(在Mac OS X 11.2上使用git v2.31.1)。这是我的会话记录:https://gist.github.com/andreaja/c2a07ecc6cc5bb332a198fd2cc78c8e8 - Andreas

130

以上所有答案都是正确的,但我认为没有提到的一点是,一旦您将目录中的文件添加到存储库中,您就不能忽略包含该文件的目录/子目录(Git 将忽略该指令)。

若要忽略已添加的文件,请运行

$ git rm -r --cached .
否则,您必须首先从存储库的目标目录中删除所有文件,然后才能忽略该文件夹。

16
如果你想让某些文件不被追踪或者与历史记录无关,但是又想在本地保留这些文件的原始版本,就可以使用命令"git rm --cached"。 - Erik Reppen
简单来说,先执行 git reset Solution 命令,然后将 Solution//bin/Debug 和 Solution//bin/Release 添加到 .gitignore 文件中,最后再执行 git add Solutions 命令。 - NotTooTechy
9
这句话的意思是:执行git rm -r --cached .命令。 - OceanFire
如何撤销此命令? - user3748973
4
我认为 git reset 可以撤销这个命令。 - Arun Girivasan
2
这个答案前面应该有一个警告,或者至少有一个加粗的免责声明来说明在哪个文件夹中运行此命令。git reset可以让你从使用git rm -r --cached .可能造成的混乱中脱身,但是你将会遇到恢复之前 git 的状态(如 git 添加和 git 删除等)的困难。而且我自己也必须记住在复制粘贴命令之前先思考。一年或两年后,我总是开始变得自鸣得意...: P - Lionel Trebuchon

82
这个问题并不是要求忽略所有子目录,但我找不到答案,所以我会发帖子: */*.

4
你能否帮我澄清一下?我尝试了各种方式,但无法让 git add 忽略一个目录及其子目录中的所有文件。我已经尝试了 dirname/dirname/*dirname/**dirname/*/*,甚至绝望地尝试了 dirname/*/*/*dirname/*/*/*/*dirname/*/*/*/*/* - Chris
4
*/*表示忽略所有子目录,但不包括当前目录中的文件。若要忽略特定的子目录,则可以使用普通的.gitignore用法,例如dirnamedirname/dirname/*。请问,在该目录中是否已经提交了任何内容? - mgold
这是一个全新的仓库 - 我在尝试之间删除整个 .git 目录,然后 git init 然后 git add --all .(也尝试过不使用 --all),使用的是 1.9.4.msysgit.1 版本。我的命名目录下的每个非空子目录都会添加到索引中(在 TortoiseGit 和 git status 中检查)。.gitignore 中没有以 ! 开头的相关行,但必须存在一些冲突。现在通过在 add 过程中删除文件夹来解决。我猜这是需要更深入挖掘才能提供必要信息进行诊断的问题。感谢您让我确认我没有误解语法。 - Chris
1
如果我需要忽略一个文件夹中的文件夹,但不是第一个文件夹怎么办?就像 forum/ignorethisfolder/ ... 但他不应该忽略名为 forum 的文件夹。 - Jean Carlos Racoski
这对我来说无法忽略以点开头的目录名称。 "/." 和 "./" 也不起作用。 - Tony

54

排除内容和子目录:

**/bin/*

如果只想排除所有子目录但保留内容,请添加“/”:

**/bin/*/

本帖最佳答案,谢谢! - d0rf47
正是我所寻找的。 - Motla

39
除了在你的.gitignore文件中正确地添加条目外,如果你试图忽略已经添加到版本库中的内容,你需要执行git rm -r /path/to/dir并提交更改,然后再将该目录添加到你的.gitignore文件中。否则,Git只会忽略你的忽略指令。

36
我在我的电脑上让它工作的唯一方法是这样做:
# Ignore all directories, and all sub-directories, and it's contents:
*/*

#Now ignore all files in the current directory 
#(This fails to ignore files without a ".", for example 
#'file.txt' works, but 
#'file' doesn't):
/*.*

#Only Include these specific directories and subdirectories:
!wordpress/
!wordpress/*/
!wordpress/*/wp-content/
!wordpress/*/wp-content/themes/

注意,您必须明确允许每个要包含的级别的内容。因此,如果我在themes下有5层子目录,我仍然需要拼写出来。
这是@Yarin在这里发表的评论:https://dev59.com/Mm435IYBdhLWcg3wvyw5#5250314 这些是有用的主题: 我也尝试过。
*
*/*
**/**

还有**/wp-content/themes/**

或者/wp-content/themes/**/*

对我来说,都没有起作用。需要进行大量的尝试和错误!


这种否定模式是实现问题中提出的任务的最正确方法。 - Supamic

20

忽略仓库根目录下所有子文件夹,但包括该文件夹根目录下的文件的最简单形式是将以下内容添加到您的 .gitignore 文件中:

*/

如果您想忽略另一个子文件夹的所有子文件夹(仍包括其中的文件):

subfolder/*/

如果您已经提交了需要被忽略的项目,您需要在将它们忽略之前从仓库中删除它们。

要删除您的仓库根目录下的所有子文件夹:

git rm -r --cached */*

删除另一个子文件夹的所有子文件夹:

git rm -r --cached subfolder/*/*

1
谢谢,我使用了 .vscode/*/我想要补充你的解决方案:“忽略子文件夹但包括此文件夹根目录下的文件。” - Meryan
谢谢,我想知道为什么将文件添加到.gitignore中没有起作用;它们已经提交到仓库中了。 - Specimen

15

要忽略所有子目录,您可以简单地使用:

**/

截至git版本1.8.2,此方法有效。


11

如果想忽略所有子文件夹,但仍继续跟踪 /bin 目录中的文件,通用的方法是将以下行添加到项目的 .gitignore 文件中:

/subfolder/*
bin/*/*

如果您只想忽略特定名称的子文件夹,可以这样做:

bin/Debug/*
bin/Release/*

注意,如果bin目录不在项目的根目录中(与.gitignore文件一起),那么您可能需要使用path/to/bin/*/*而不是例如bin/*/*


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接