gitignore删除文件夹中的所有文件,但保持文件夹结构

Dav*_*ber 8 git gitignore

我具有以下文件夹结构:

/foo/
/foo/test.txt
/foo/.gitkeep
/foo/bar/test.txt
/foo/bar/.gitkeep
/foo/bar/baz/test.txt
/foo/bar/baz/.gitkeep
Run Code Online (Sandbox Code Playgroud)

现在,我想排除“ foo”文件夹中的所有文件及其子文件夹(和子子文件夹)中的所有文件,但不包括所有.gitkeeps(以便保留文件夹结构)。这也应该适用于3个以上级别的子文件夹。

以下gitignore-rules起作用:

/foo/**
!/foo/**/
!/foo/**/.gitkeep
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下,这为什么起作用吗?有没有更干净的方法可以做到这一点?

Von*_*onC 14

规则很简单:

如果排除该文件的父目录,则无法重新包含该文件。

这就是为什么你需要

(如果只忽略/foo/,即文件夹,那么将不使用任何数量的“ !”排除规则,因为foo/文件夹本身将被忽略:Git将在此处停止)

.gitkeep是可行的,因为父文件夹已从忽略规则中排除。

与伯纳多(Bernardo)的原始建议相反(在他编辑之前):

/foo/** 
!**/.gitkeep
Run Code Online (Sandbox Code Playgroud)

如果没有从/**忽略规则中排除文件夹,则文件的排除规则无效。

您可以使用以下方法进行检查:

git check-ignore -v -- /path/to/.gitkeep
Run Code Online (Sandbox Code Playgroud)

scm中所述.gitignore

  • 使用“ *”与“ **” 相同
  • 使用!.gitkeep(不带/锚)将递归排除该文件。

在这两种情况下,“ recursively”是解释为什么可以应用排除规则的关键术语:如果忽略文件夹(如./foo/),则将无法排除该文件夹中的任何内容。
但是,如果您递归地***)忽略元素(文件和文件夹),从gitignore规则中排除文件夹(再次通过递归规则!*),可以排除(白名单)文件。

  • 这次真是万分感谢!我已经看了很多,但所有 .gitkeep 解决方案都没有提及递归忽略和异常背后的逻辑。 (3认同)

Ber*_*rte 6

我已经做到了。似乎需要的是.gitignore所需文件夹中的文件。

看看这个存储库,它完全符合你的要求。

我试着添加任何文件名内foo/foo/bar/并且foo/bar/baz/但是它只接受.gitkeep。

诀窍是在文件夹内创建一个包含此内容的 .gitignore :

*
!*/
!.gitignore
!.gitkeep
Run Code Online (Sandbox Code Playgroud)

[编辑:根据评论添加]

您应该能够将其缩短为:

*
!*/
!.git*
Run Code Online (Sandbox Code Playgroud)

尽管将来可能不太清楚其意图是什么。

虽然此解决方案不会缩短原始文件所需的行数.gitignore,但它确实有其他几个优点 - 主要是这将是.gitignore文件夹内的一个文件,这意味着它可以是一个只有这些行的干净文件, 并且仅针对此文件夹。

这意味着该.gitignore文件可以轻松移动到任何需要此过滤器的特定文件夹中。此外,整个文件夹可以在 repo 中轻松移动,甚至可以移动到不同的 repo,而无需修改.gitignore. 它更干净,更易于维护,并且不会隐藏在.gitignorerepo 根文件夹中的典型大文件中。