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分支(我在此处抬起)。
解决此问题的一种方法是进行以下操作:
- 将其添加到您的
.gitignore
:
data/**
!data/**/
!data/**/.gitkeep
git add data
从您的.gitignore删除第二行:
data/**
# !data/**/
!data/**/.gitkeep
git add .gitignore
git commit
这将数据目录结构提交给git,并确保任何未来的git
调用都将完全忽略您的数据子目录的内容。
不能将空目录用于git。因此,创建一个readme.md文件或任何空文件,然后忽略所有其他文件(使用模式匹配)。此方式目录将使用占位符文件进行。