我具有以下文件夹结构:
/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/**
Run Code Online (Sandbox Code Playgroud)(如果只忽略/foo/,即文件夹,那么将不使用任何数量的“ !”排除规则,因为foo/文件夹本身将被忽略:Git将在此处停止)
然后从忽略规则中排除文件夹:
!/foo/**/
Run Code Online (Sandbox Code Playgroud)在将文件列入白名单之前.gitkeep
!/foo/**/.gitkeep
Run Code Online (Sandbox Code Playgroud)这.gitkeep是可行的,因为父文件夹已从忽略规则中排除。
与伯纳多(Bernardo)的原始建议相反(在他编辑之前):
/foo/**
!**/.gitkeep
Run Code Online (Sandbox Code Playgroud)
如果没有从/**忽略规则中排除文件夹,则文件的排除规则无效。
您可以使用以下方法进行检查:
git check-ignore -v -- /path/to/.gitkeep
Run Code Online (Sandbox Code Playgroud)
*”与“ **” 相同!.gitkeep(不带/锚)将递归排除该文件。在这两种情况下,“ recursively”是解释为什么可以应用排除规则的关键术语:如果忽略文件夹(如.或/foo/),则将无法排除该文件夹中的任何内容。
但是,如果您递归地(*或**)忽略元素(文件和文件夹),并从gitignore规则中排除文件夹(再次通过递归规则!*),则可以排除(白名单)文件。
我已经做到了。似乎需要的是.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 根文件夹中的典型大文件中。