gitignore文件夹中的所有文件,但要保留文件夹结构



i具有以下文件夹结构:

/foo/
/foo/test.txt
/foo/.gitkeep
/foo/bar/test.txt
/foo/bar/.gitkeep
/foo/bar/baz/test.txt
/foo/bar/baz/.gitkeep

现在,我想将所有文件及其子文件夹(和亚申请人)中的所有文件中排除,除了所有.gitkeeps(以便保留文件夹结构)。这也应该适用于3个以上的子文件夹。

以下gitignore-rules工作:

/foo/**
!/foo/**/
!/foo/**/.gitkeep

有人可以解释,为什么这起作用?是否有更干净的方法?

规则很简单:

如果排除该文件的父目录,则不可能重新包含文件。

这就是为什么您需要

  • 递归忽略文件和文件夹:

    /foo/**
    

(如果您仅忽略/foo/,那是文件夹,则' !'排除规则的数量都不会起作用,因为 foo/文件夹本身被忽略:git将会停止)

  • 然后将文件夹从忽略规则中排除:

    !/foo/**/
    
  • .gitkeep

    !/foo/**/.gitkeep
    

之所以有效,是因为.gitkeep父文件夹不包括在忽略规则中。

而不是伯纳多原始提案(在他的编辑之前):

/foo/** 
!**/.gitkeep

如果不从/**忽略规则中排除文件夹,则 files的排除规则不起作用。

您可以通过以下方式检查一下:

git check-ignore -v -- /path/to/.gitkeep

SCM .gitignore中提到:

  • 使用' *'与' **'
  • 相同
  • 使用!.gitkeep(无/锚)将递归排除该文件。

在这两种情况下,' recursively'都是关键术语,解释了为什么排除规则可以应用:如果您忽略文件夹(例如./foo/),您将无法在该文件夹中排除任何内容。


但是,如果您忽略元素(文件和文件夹)递归***),将gitignore规则中的文件夹排除(再次通过递归规则!*),然后然后您可以排除(白列)文件。

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

查看此存储库,它确实可以完成您想要的。

我尝试在foo/foo/bar/foo/bar/baz/中添加任何文件名,但它仅接受.gitkeep。

诀窍是在文件夹中使用此内容创建一个.gitignore :

*
!*/
!.gitignore
!.gitkeep

[编辑:基于注释添加]

,您应该能够将其缩短到:

*
!*/
!.git*

尽管将来可能不太清楚。

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

这意味着可以轻松地将此.gitignore文件移至需要此过滤器的任何特定文件夹中。同样,整个文件夹可以轻松地在存储库中移动,甚至可以移动到其他存储库,而无需修改.gitignore。它更干净,更可维护,并且不埋葬在回购根文件夹中通常大的.gitignore文件中。

我没有足够的声誉来发表评论,但我想提出一个重要的问题:

  • 使用已安装的数据文件夹,这是由于 git 命令(例如git status)运行非常缓慢地运行,因为命令仍然浏览所有文件(尽管没有提交所有文件)他们),将通过网络缓慢运行。

  • 更不可预测的是,这会导致哦,我的zsh (如果已安装)在每个命令后悬挂一段时间,因为它会静静地检查git分支(我在此处抬起)。

解决此问题的一种方法是进行以下操作:

  1. 将其添加到您的.gitignore
data/**
!data/**/
!data/**/.gitkeep
  1. git add data

  2. 从您的.gitignore删除第二行:

data/**
# !data/**/
!data/**/.gitkeep
  1. git add .gitignore

  2. git commit

这将数据目录结构提交给git,并确保任何未来的git调用都将完全忽略您的数据子目录的内容。

不能将空目录用于git。因此,创建一个readme.md文件或任何空文件,然后忽略所有其他文件(使用模式匹配)。此方式目录将使用占位符文件进行。

最新更新