如何告诉Git忽略除了一个子目录以外的所有内容?

274

我想忽略仓库中除了位于bin子目录下的文件之外的所有文件。我尝试将以下内容添加到我的.gitignore文件中:

*
!bin/*

然而,这并没有产生预期的效果:我在 bin/ 下创建了一个新文件,但是运行 git status 仍然显示 nothing to commit (working directory clean)

有什么建议吗?


13个回答

335

这个命令忽略根目录下的文件和目录,然后取消忽略根目录下的bin目录:

/*
/*/
!/bin/

这种方式可以获取所有的bin目录,包括其子目录和文件。


31
出于某种原因,这对我来说不能保持一致。我有两行代码/stuff/!/stuff/specific/,但它仍然忽略了/stuff/specific/ - LB--
1
@LB-- 我曾经遇到过类似的问题,git check-ignore -v 告诉我是因为 ~/.gitignore 的原因。 - gurney alex
4
/*/是否必要? - Alex Baker
3
这对我没有起作用。我不得不在我的根.gitignore文件中添加 !/bin/,然后另外再添加一个 /bin/.gitignore 文件,其中包含 !*... 只进行其中一个更改是不起作用的,只有将这两个更改结合起来才有效。 - Felipe Brahm
7
@LB 和其他人,尝试使用 /stuff/*!/stuff/specific/。它们之间的区别在于 /stuff/ 告诉程序忽略 stuff 目录本身,而 /stuff/* 表示忽略 stuff 目录中的所有子目录,但不要忽略特定的目录。这对我来说起了作用。 - reads0520
显示剩余3条评论

142

如何忽略某个目录以外的所有内容,只保留一个目录 "MY_SUPER_DUPER_TEMPLATE_directory" 呢?

目录结构: /bitrix/templates/MY_SUPER_DUPER_TEMPLATE_directory

/*
!/bitrix
/bitrix/*
!/bitrix/templates
/bitrix/templates/*
!/bitrix/templates/MY_SUPER_DUPER_TEMPLATE_directory
*.DS_Store
*.gitignore

3
这对于解除我修改过的Laravel供应商包的被忽略问题非常有效!谢谢你,你帮我省去了很多麻烦。 - Maria Vilaró

79

到达目的地时,您必须排除路径上的所有内容,但必须包括目的地:

注意:这是一个排除文件(即.gitignore),因此逻辑是反过来的。忽略所有内容,除了tsp目录,忽略tsp目录中的所有内容,除了src目录...

/*
!/tsp
/tsp/*
!/tsp/src
/tsp/src/*
!/tsp/src/*.h
!/tsp/src/*.cpp
!/tsp/src/data.txt
!/.gitignore

11
支持包含一个目录的原则,然后排除它的内容,再包含所需的子目录等。我最终在我的项目中使用了这个答案。 - John Jesus
快进几年,你仍然需要这么冗长的代码感觉有点不对劲。指定最终目的地应该足够了。 - Mig82

45

你唯一的问题是bin/*这个匹配模式并不包括bin目录本身,所以git甚至都不会查看bin目录。

有两个解决方案:

.gitignore文件:

*
!/bin/
!bin/*

.gitignore

*
!/bin/

bin/.gitignore

!*

我更偏向于第二种解决方案,因为第一种方案不会停止忽略位于子目录中且不叫做 binbin 目录下的文件。在您的情况下,这可能重要,也可能不重要。


2
对我没用。我必须像这样拥有一个.gitignore才能使它工作:

忽略所有

但不是这些文件...

!/wp-content/ !/wp-content/plugins/ !/wp-content/plugins/my_plugin/ !/wp-content/plugins/my_plugin/*注释中没有代码块?
- xlttj
1
Tyler的答案有更好的单文件解决方案。 - Yarin

27

根据官方Git文档,其中一个例子说明:

例子:排除所有内容,除了特定的目录foo/bar(请注意/* - 如果没有斜杠,则通配符也会排除foo/bar中的所有内容):

$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar

关于前导斜杠的解释:如何在.gitignore中使用前导斜杠


1
非常感谢,这对我很有帮助!提醒其他人注意这里的行顺序很重要,例如你不能在/foo/*之前放置!/foo/bar。 - Iamsodarncool

16

请尝试使用最新的GIT版本。

*
!*/
!/path/to/your/dir/**

1
最后一行应该是 !/path/to/your/dir/**。 - faham
@faham,是的,我刚刚添加了它。 - Kirby

12

我认为更好的方法是通过在模式之前加上斜杠,将每个模式锚定到顶层git目录:

/*
!/public_html
!/.gitignore

它不会忽略所有文件,而是只会忽略顶层的文件,而不是您不想忽略的目录中的文件。


9
这个 .gitignore 对我很有效:

*/
/*
!bin/

9

虽然我来晚了,但是没有一个答案能够“一步到位”地解决我的问题。这个可以:

* 
!bin
!bin/**
  • 第一行忽略所有内容。
  • 第二行包括 "bin" 目录本身。
  • 最后一行包括 "bin" 目录的全部内容,无论嵌套多少层(注意双星号)。

6

尝试一下这个不太常见的git bug。

!bin**/**

希望这能有所帮助 :)
支持文件 git bug 示例
附注:在评论之前请先尝试一下。

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