题 如何将空目录添加到Git存储库?


如何将空目录(不包含文件)添加到Git存储库?


3477
2017-09-22 16:41


起源


虽然它没用, 有一种方法可以将空(真空)目录破解到您的仓库中。它不会 checkout 但是,使用当前版本的Git。 - tiwo
@tiwo我一个人不同意这是没用的。您的目录层次结构是项目的一部分,因此它应该受版本控制。 - JBentley
在我的例子中,我想为tmp文件添加目录结构,但不是tmp文件本身。通过这样做,我的测试人员具有正确的结构(否则有错误),但我不会使用tmp数据阻塞我的提交。是的,这对我很有用! - Adam Marshall
@AdamMarshall我认为tiwo说黑客没用,因为它被结账忽略了。 Tmp dirs听起来像VCS的有用功能。 - Quantum7
为什么不创建tmp文件的过程也创建tmp目录? - RyPeck


答案:


使目录保持为空(在存储库中)的另一种方法是创建一个 .gitignore 该目录中包含以下四行的文件:

# Ignore everything in this directory
*
# Except this file
!.gitignore

然后你不必按照m104中的方式完成订单

这样做的好处是,当你执行git状态时,该目录中的文件不会显示为“未跟踪”。

制造 @GreenAsJade评论持久性:

我认为值得注意的是,这个解决方案确切地解决了问题所要求的问题,但也许不是许多人在看这个问题时会一直在寻找的。此解决方案可确保目录保持为空。它说“我真的不想在这里检查文件”。与“我在这里没有任何要检查的文件相反,但我需要这里的目录,文件可能会在以后”。


3365
2018-05-31 22:10



我认为值得注意的是,这个解决方案确实如此 恰恰 这个问题要求的是什么,但也许不是许多人在看这个问题时会一直在寻找的。这个解决方案 保证目录保持为空。它说“我真的不想在这里检查文件”。与“我在这里没有任何要检查的文件相反,但我需要这里的目录,文件可能会在以后”。 - GreenAsJade
我认为@JohnMee提出的README解决方案应该和这个一起使用; .gitignore文件提供了我们想要阻止版本控制的解释,而README文件解释了目录的目的是什么,这两者都是非常重要的信息。 - pedromanoel
@pedromanoel我写了你要放入的文档 README 在 - 的里面 .gitignore 文件(作为评论)。 - Carlos Campderrós
发现1个区别:1。)一个空文件夹,2。)一个带有.gitignore文件的文件夹。 ;-) - Peter Perháč
从技术上讲,这不是一个空目录...... - Arash Saidi


你不能。见 Git FAQ

目前设计的git索引   (暂存区)只允许文件到   被列出,没有人能胜任   使更改允许为空   目录已经足够关心了   这种情况可以解决它。

目录会自动添加   在其中添加文件时。那   是,目录永远不必添加   到存储库,并没有被跟踪   他们自己。

你可以说 ”git add <dir>“而它   将在那里添加文件。

如果你真的需要一个目录   在结帐时你应该创建一个   文件在里面。 .gitignore效果很好   这个目的;你可以把它留空   或填写您的文件名称   期望出现在目录中。


983
2017-09-22 16:42



以下答案更好。 git低级软件不允许它对我来说无关紧要,因为我需要一个空目录时实际使用Git。添加2行.gitignore似乎对我来说是可以接受的。 - Amala
好吧,如果有人想将文件移动到新目录中,他们就无法完成 git mv 因为git会抱怨新目录不受版本控制 - lulalala
你可以阅读 ”这是不可能的,你不能,等等。“这是一个经常出现问题的互联网 .gitignore 技巧是一个经常回答,满足了许多需求。然而 有可能的 使git跟踪 真的很空 目录, 看到我的回答 - ofavre
虽然我想的越多,它就越像“空字符串的SHA哈希”,如果它存在,实际上 将 是一个明确定义的空树标识符,除非无法判断该对象是树还是blob。 - Emil Lundberg
我见过很多使用空文件的repos .gitkeep 以此目的。 - Sukima


创建一个名为的空文件 .gitkeep 在目录中,并添加。


598
2017-12-07 16:03



+1这是为什么文件首先在那里的交流 - djhaskin987
我添加了一个 回答 鼓励创造 .keep 代替。 - A-B-B
.gitkeep Git没有规定,并且会让人们再次猜测它的含义,这将导致他们进行谷歌搜索,这将引导他们到这里。该 .git 应该为Git本身使用的文件和目录保留前缀约定。 - t-mart
@ t-mart“The .git 应保留前缀约定......“为什么?git是否请求此预订? - Limited Atonement
它没有。关键是它可能令人困惑。 - szablica


您始终可以将README文件放在目录中,并说明您为什么要在存储库中使用此目录(否则为空)。


368
2018-03-14 23:38



+1,好建议,空目录没有任何意义,除非它将来会被使用。因此,在其中创建一个README文件并写下该目录的用途,以及将来将放置哪些文件。这解决了两个问题。 - saeedgnu
我同意。空文件夹很烦人,应该在所有正确处理的任何类型的存储库中进行解释。 - Sold Out Activist
@ilius废话。在许多情况下,包含空目录的目录结构可能是非常需要的(比如MVC应用程序,您需要模型目录但尚未创建任何模型,或者您计划添加共享视图的共享视图目录) )。而且,在每一个中加入README都是过度的,因为很明显它们的用途是什么,并且很容易忘记在每一个中放入README。并且您必须记住在向其添加一些其他文件时删除README。基本上,git应该绝对允许空目录。 - Jez
@Jez:我不同意。关键是git旨在控制(和索引)源代码。重要的是,提交的id是内容的哈希。也就是说,它必须有内容。您不需要自述文件 一切 树的一部分,只有叶节点。如果你有打算放置代码的地方,但没有代码,你甚至不会花时间回应“模型的地方”>> README,那么你所拥有的是一个想法而不是提交。它对git不感兴趣。说“我希望正在运行的应用程序有XYZ空目录”是一个 运行 问题,不是源问题。用你的安装程序处理它。 - Joe Atzberger
@ jbo5112是的,你提到的“特殊代码”是我提到的“安装程序”。您的webapp安装已经必须处理创建数据库,本地配置,拉动依赖项或其他100个操作,但是除了它之外还有几个空目录?尝试使用gradle,passenger,chef,原始Makefile等。创建目录与安装应用程序的其他(可能更复杂/危险)工作之间没有安全性差异。如果你真的没有deps,config,DB等,也没有安装程序,那么只需使用自述文件。没有案例要求你同时做到这两点。 - Joe Atzberger


touch .keep

在Linux上,这会创建一个名为的空文件 .keep。此名称优先于 .gitkeep 因为前者对Git不可知,而后者则与Git无关。其次,正如另一位用户所说, .git 应该为Git本身使用的文件和目录保留前缀约定。

或者,如另一个所述 回答,该目录可以包含描述性 README 要么 README.md 文件 代替。

当然,这要求文件的存在不会导致应用程序中断。


261
2018-01-29 04:29



这对于初始裸目录很有用,但如果它开始填充文件呢?然后Git会注意到它们并声称它们是未跟踪的文件。这里选择的答案更加优雅,允许一个人保留一个目录,然后安全地忽略这些内容。 - JakeGould
问题和主要的普遍关注是添加一个空目录。如果以后有驻留文件,显然删除了 .keep 文件或只是忽略它。如果要忽略目录中的文件,那么这完全是另一个问题。 - A-B-B
有人建议 git clean -nd | sed s/'^Would remove '// | xargs -I{} touch "{}.keep" 将在所有未跟踪的空目录中执行此操作。 - A-B-B
不喜欢这个解决方案,很难猜出这个文件的作用。此外,如果您在开发环境中生成文件(如日志或图像等),这不会使这些文件不被版本化并进入生产状态,这并不好。 - danielrvt
Windows不喜欢没有名字的文件,并且需要特殊的魔法来实现这一点(也就是类似bash的终端应用程序或同等版本)。 - EntangledLoops


为什么我们需要空的版本化文件夹

首先要做的事情:

一个空目录 不能成为Git版本控制系统下树的一部分

它根本不会被跟踪。但有些情况下,“版本控制”空目录可能很有用,例如:

  • 建设一个 预定义文件夹结构 对于有用的项目文件夹,并使该结构可用于存储库的每个用户/贡献者;或者,作为上述的一个特例,创建一个文件夹 临时文件, 比如一个 cache/ 要么 logs/ 目录
  • 一些项目 没有一些文件夹就行不通 (这通常暗示了一个设计不佳的项目,但这是一个经常出现的现实场景,也许可能存在许可问题)。

一些建议的解决方法

许多用户建议:

  1. 放置一个 README 文件或包含某些内容的其他文件,以使目录非空,或
  2. 创建一个 .gitignore 文件具有一种“反向逻辑”(即包括所有文件),最后,它们用于方法#1的相同目的。

两种解决方案肯定都有效 我发现他们对Git版本化的有意义的方法不一致。

  • 你为什么要把伪造的文件或自述文件放在你的项目中?
  • 为何使用 .gitignore 做一件事(保持 文件)与其意图完全相反(排除 文件),即使有可能吗?

.gitkeep方法

用一个  文件叫 .gitkeep 为了强制在版本控制系统中存在文件夹。

虽然看起来似乎没有那么大的区别:

  • 您使用具有的文件  保留文件夹的目的。你没有放任何你不想放的信息。

    例如,你应该使用自述文件作为有用信息的自述文件,而不是保留文件夹的借口。

    关注点分离总是一件好事,你仍然可以添加一个 .gitignore 忽略不需要的文件。

  • 命名它 .gitkeep 从文件名本身(也是如此)使它变得非常清晰和直接 给其他开发者,这对于共享项目和Git存储库的核心目的之一是这个文件的好处

    • 与代码无关的文件(因为前导点和名称)
    • 一个与Git明显相关的文件
    • 它的目的(保持)在其含义中明确陈述,一致和语义上相反 忽视

采用

我见过了 .gitkeep 非常重要的框架所采用的方法 Laravel角CLI


204
2017-12-04 23:32



你错过了一个想法 - 什么是保留和清空文件夹的原因(例如/ logs,/ tmp,/ uploads)?是的 - 它保持文件夹为空。 :)因此,如果您想将文件夹保留为空,则必须忽略其中的文件。 - Roman
@RomanAllenstein:不一定。可能是您创建了一个具有给定结构的仓库,该仓库可以在以后填充。这些文件一旦创建就会被添加到repo中,开始删除或编辑.gitignore文件会很烦人(而且很危险,因为可能你甚至没有意识到它们没有被跟踪:git忽略它们) - dangonfast
downvote:详细的回答。 - Behnam
@Behnam:我会采取行动,但我对S.O.的研究meta表示不关心冗长的答案,只要它们提供足够的细节和清晰度,对每个读者(以及每个技能水平)都有用。我仍然对任何批评持开放态度,并感谢你公开宣布这个理由,我非常积极地接受。 - Cranio
如果您编辑要替换的答案 .gitkeep 与任何其他非git前缀的文件名你得到我的upvote,我认为这是最好和最丰富的答案。原因:我认为应该为git规定的文件保留“.git *”,而这只是一个占位符。我第一次猜到的是,例如“.gitkeep”文件会被自动忽略(这将是一个很好的功能)但事实并非如此,对吧? - Johnny


如其他答案中所述,Git无法在其临时区域中表示空目录。 (见 Git FAQ。)但是,如果为了您的目的,如果目录是空的,如果它包含一个 .gitignore 只有文件,然后你可以创建 .gitignore 空目录中的文件只能通过:

find . -type d -empty -exec touch {}/.gitignore \;

119
2018-05-03 15:17



您可能想忽略.git目录: find . -name .git -prune -o -type d -empty -exec touch {}/.gitignore \; - steffen
大多数情况下更简单的变化是 find * -type d -empty -exec touch {}/.gitignore \; - akhan
由于OS X几乎在每个directoy中都创建了一个.DS_Store文件,因此这不起作用。我发现的唯一(危险!)解决方法是首先删除所有.DS_Store文件 find . -name .DS_Store -exec rm {} \; 然后使用此答案中的首选变体。务必只在正确的文件夹中执行此操作! - zerweck
有没有人知道从命令行在Windows中执行此操作的方法?我在Ruby和Python中已经看到了一些解决方案,但如果可以管理它,我想要一个准系统解决方案。 - Mig82
@akhan添加内容 .gitignore 没有影响 -empty 的旗帜 find 命令。我的评论是关于删除 .DS_Store 目录树中的文件,所以 -empty 可以应用标志。 - zerweck