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

Lau*_*ung 4039 git directory git-add

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

Jam*_*noy 3906

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

# Ignore everything in this directory
*
# Except this file
!.gitignore
Run Code Online (Sandbox Code Playgroud)

然后,您不必按照m104 解决方案中的方式完成订单.

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

@GreenAsJade的评论持久:

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

  • 发现1个区别:1.)一个空文件夹,2.)一个带有.gitignore文件的文件夹.;-) (55认同)
  • 我认为@JohnMee提出的README解决方案应该和这个一起使用; .gitignore文件提供了我们想要避免版本控制的解释,而README文件解释了目录的目的是什么,这两者都是非常重要的信息. (21认同)
  • @pedromanoel我在`.gitignore`文件中写了你要放在`README`中的文档(作为注释). (15认同)
  • 不幸的是,这导致非空目录,它有一个隐藏文件. (7认同)
  • 这非常适合*cache*文件夹. (4认同)
  • "Just add a README"解决方案的问题在于,应用程序多次进入目录并设置来自(临时)文件的值,这些文件放在此另外的空目录中.我喜欢实际强制git保持空的想法,因为这可能是应用程序想要/需要的东西. (3认同)
  • 这对于源外构建非常有用,您不希望检入任何二进制文件但不希望用户手动创建文件夹(以防您的构建系统无法处理). (3认同)
  • @GreenAsJade如果我理解答案,这并不能完全符合OP的要求.这将创建一个目录,其中包含一个文件,而不是空目录.就我而言,我想要一个空目录. (3认同)
  • @GreenAsJade实际上,由于目录*不为空*,它不能*精确地*所要求的内容.正如其他用户所建议的那样,以"git"为前缀是一个坏主意,因为它具有误导性 - 这不是一种"git意识"策略. (3认同)
  • @CarlosCampderrós也来这里说!我把一个.gitignore放到空目录中,注释"#这个空目录需要检入git".当您真正想要将某些内容放入目录并忘记您聪明的.gitignore指令时,这个答案可能会出现问题. (2认同)
  • @GreenAsJade后者更像是一个`.gitkeep`用例 (2认同)
  • 虽然好建议 - 没有必要忽略文件本身 - 要么创建文件并强制添加它(`echo"*"> .gitignore; git add -f .gitignore;`)或添加文件并编辑它(` touch .gitignore; git add .gitignore; echo"*"> .gitignore).这消除了一些毫无意义的"但不要忽略.gitignore"规则. (2认同)
  • 通常,目录的目的是包含文件。如果您想向存储库添加一个空目录,它可能最终会包含文件,至少在其中一个存储库或发行版中。但是您可能不希望这些文件成为存储库的一部分,否则它可能已经包含一个或多个这些文件,或者您可以等到添加它们。因此,对于您实际上想要存储库中的“空”目录的主要情况,此解决方案是完美的。 (2认同)
  • @pedorro 在某些情况下这正是你想要的。 (2认同)

And*_*ter 1055

你不能.请参阅Git常见问题解答.

目前git索引(临时区域)的设计只允许列出文件,没有人能够进行更改以允许空目录已经足够关注这种情况来弥补它.

在其中添加文件时会自动添加目录.也就是说,目录永远不必添加到存储库中,并且不会自己跟踪.

你可以说" git add <dir>",它会在那里添加文件.

如果您确实需要在结帐中存在目录,则应在其中创建一个文件..gitignore很适合这个目的; 您可以将其留空,或填写您希望在目录中显示的文件的名称.

  • 以下答案更好.git低级软件不允许它对我来说无关紧要,因为我需要一个空目录时实际使用Git.添加2行.gitignore似乎对我来说是可以接受的. (64认同)
  • 为了这个目的,我看过很多使用名为`.gitkeep`的空文件的repos. (19认同)
  • 对于这个常见的问题,你可以在互联网上阅读"_it不可能,你不能,等等_".`.gitignore`技巧是一个经常回答,满足了许多需求.但是**有可能**让git跟踪**真正空的**目录,[见我的回答](http://stackoverflow.com/questions/115983/how-do-i-add-an-empty -directory到一个-GIT-库/ 8944077#8944077) (15认同)
  • 虽然我越想到它,感觉就像"空字符串的SHA哈希"一样,如果它存在,实际上_would_是一个明确定义的空树标识符,除非无法判断该对象是否是树或blob. (2认同)

Art*_*r79 692

创建一个.gitkeep在目录中调用的空文件,然后添加它.

  • Git没有规定`.gitkeep`,并且会让人们再次猜测它的含义,这将引导他们进行谷歌搜索,这将引导他们到这里.应该为Git本身使用的文件和目录保留`.git`前缀约定. (183认同)
  • 我添加了一个[回答](http://stackoverflow.com/a/21422128/832230)鼓励创建`.keep`. (54认同)
  • 它没有.关键是它可能令人困惑. (46认同)
  • @ t-mart"应该保留`.git`前缀约定......"为什么?请问这个预订? (9认同)
  • 在这种情况下,`README`或`ABOUT`文件将同样好或更好.给下一个人留一张纸条,就像我们以前在URL之前做过的那样. (8认同)
  • @t-mart 将其称为“.gitkeep”的一个主要优点是,看到该文件的开发人员会立即明白其用途与 git 有关。搜索可能将他们引导到这里的事实也意味着他们可以快速找出放在那里的人的意图,而明确的意图对于软件来说是黄金。 (5认同)
  • 这个答案正在[元上讨论](https://meta.stackoverflow.com/q/421153/73226) (4认同)
  • 如果您正在编写应在空目录上测试代码的单元测试,则不起作用... (3认同)
  • 使用“.keep”的理由非常充分。简单和不那么混乱之间的良好平衡。请参阅其他答案 http://stackoverflow.com/a/21422128/832230 如果您已采用 .gitkeep 习惯,请在您的存储库上运行此命令: `git mv .gitkeep .keep` (3认同)
  • @szablica我觉得它根本不会让人感到困惑.事实上,我认为称之为.gitkeep是非常直观的.把它称为.gitignore听起来与我相矛盾.所以这只是个人品味的问题. (2认同)
  • @szablica,每件事都让某人感到困惑¯\\_(ツ)_/¯ (2认同)
  • `.emptydir` 可能比 `.gitkeep` 更容易混淆。 (2认同)

Joh*_*Mee 414

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

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

Acu*_*nus 313

touch .keep
Run Code Online (Sandbox Code Playgroud)

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

或者,如另一个答案中所述,目录可以包含描述符READMEREADME.md文件.

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

  • 问题和主要的普遍关注是添加一个空目录.如果它以后有一个驻留文件,显然删除`.keep`文件或忽略它.如果要忽略目录中的文件,那么这完全是另一个问题. (13认同)
  • 有人建议`git clean -nd | sed s /'^会删除'// | xargs -I {} touch"{} .keep"`将在所有未跟踪的空目录中执行此操作. (3认同)
  • 优雅:`.keep` 文件_连同提交消息_显示了“保留”项目结构的意图。添加自述文件或关于我认为会引起更多混乱... (2认同)
  • 使用“.keep”而不是“.gitkeep”的理由非常充分。简单和不那么混乱之间的良好平衡。命名空间看起来很重要,不应该破坏“.git...”看起来像 git 自己的文件命名空间。其他文档可以是项目的全局自述文件或编码风格指南或本地自述文件。如果您已经采用了 .gitkeep 习惯,只需找到这些文件并将其重命名为:`git mv .gitkeep .keep`。迎接改变!git 文档推荐的“.gitignore”解决方案似乎是一个很棘手的解决方案,而且过于复杂。 (2认同)

Cra*_*nio 290

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

首先要做的事情:

空目录不能是Git版本控制系统下树的一部分.

它根本不会被跟踪.但是有些情况下"版本控制"空目录可能有意义,例如:

  • 脚手架预定义的文件夹结构,使其可供存储库的每个用户/贡献者使用; 或者,作为上述的一个特例,为我们想要提供文件夹但其内容的临时文件(如a cache/logs/目录)创建一个文件夹.gitignore
  • 与上述相关,有些项目在没有一些文件夹的情况下将无法运行(这通常是一个设计不良的项目的暗示,但这是一个经常出现的现实场景,也许可能会有,例如,许可问题需要解决).

一些建议的解决方法

许多用户建议:

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

虽然两种解决方案确实有效,但我发现它们与Git版本化的有意义的方法不一致.

  • 你为什么要把伪造的文件或自述文件放在你的项目中?
  • 为什么要使用.gitignore(保留文件)与其意图(文件除外)完全相反的东西,即使它有可能?

.gitkeep方法

使用调用的文件.gitkeep以强制在版本控制系统中存在该文件夹.

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

  • 您使用的文件具有保留文件夹的唯一目的.你没有把任何你不想放的信息放在那里.

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

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

  • 命名它.gitkeep使文件本身(以及其他开发人员,这对于共享项目和Git存储库的核心目的之一)非常清晰和直接,这个文件是

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

采用

我已经看到了.gitkeepLaravel,Angular-CLI这样非常重要的框架所采用的方法.

  • @Behnam:我会选择downvote,但是我对SO meta的研究并不关心冗长的答案,只要它们提供足够的细节和清晰度对每个读者(以及每个技能水平)都有用.我仍然对任何批评持开放态度,并感谢你公开宣布这一理由,我非常积极地接受. (44认同)
  • @RomanAllenstein:不一定.可能是您创建了一个具有给定结构的仓库,该仓库可以在以后填充.这些文件一旦创建就会被添加到repo中,开始删除或编辑.gitignore文件会很烦人(而且很危险,因为可能你甚至没有意识到它们没有被跟踪:git忽略它们) (14认同)
  • 你错过了一个想法 - 什么是保留和清空文件夹的原因(例如/ logs,/ tmp,/ uploads)?是的 - 它保持文件夹为空.:)因此,如果您想将文件夹保留为空,则必须忽略其中的文件. (6认同)
  • 如果您编辑答案以将“ .gitkeep”替换为任何其他非git前缀的文件名,您将得到我的认可,我认为这是最好,最有用的答案。原因:我认为应该为git规定的文件保留“ .git *”,但这只是一个占位符。我的第一个猜测是,例如,“。gitkeep”文件将被自动忽略(这将是一个不错的功能),但事实并非如此,对吧? (4认同)
  • 我不知道为什么人们很难理解为什么要向git添加“空”文件夹。您必须从某个地方开始,对不对?因此,通常您从项目文件夹结构开始-las-在项目开始时还没有任何东西。项目回购完成后,团队工作人员可以克隆并开始使用SAME结构。 (2认同)

mjs*_*mjs 125

如其他答案中所述,Git无法在其临时区域中表示空目录.(请参阅Git常见问题解答.)但是,如果目录是空的,如果它只包含一个.gitignore文件,那么.gitignore只能通过以下方式在空目录中创建文件:

find . -type d -empty -exec touch {}/.gitignore \;
Run Code Online (Sandbox Code Playgroud)

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

Ari*_*zis 65

安迪·莱斯特是正确的,但如果你的目录只需要为空,而不是空的空的,你可以把一个空.gitignore文件,在那里作为一种解决方法.

顺便说一下,这是一个实现问题,而不是基本的Git存储设计问题.正如在Git邮件列表中多次提到的那样,没有实现这一点的原因是没有人关心为它提交补丁,而不是它不能或不应该完成.

  • 这正是我所说的.这两段都在我发布的常见问题解答中解决. (4认同)
  • 当然,这个额外的答案确实可以指出这个事实. (2认同)

vid*_*unj 41

在空目录中添加.gitkeep文件并提交。

touch .gitkeep
Run Code Online (Sandbox Code Playgroud)

.gitkeep是一个隐藏文件,在linux运行命令中列出它

ll -a
Run Code Online (Sandbox Code Playgroud)


Tho*_*s E 32

Ruby on Rails的日志文件夹的创建方式:

mkdir log && touch log/.gitkeep && git add log/.gitkeep
Run Code Online (Sandbox Code Playgroud)

现在日志目录将包含在树中.它在部署时非常有用,因此您不必编写例程来创建日志目录.

可以通过发出来保留日志文件,

echo log/dev.log >> .gitignore
Run Code Online (Sandbox Code Playgroud)

但你可能知道这一点.

  • 这与Ruby on Rails有什么关系? (22认同)

les*_*ana 28

Git不跟踪空目录.有关更多说明,请参阅Git FAQ.建议的解决方法是将.gitignore文件放在空目录中.我不喜欢这个解决方案,因为它.gitignore被Unix惯例"隐藏"了.也没有解释为什么目录是空的.

我建议在空目录中放一个README文件,解释为什么目录为空以及为什么需要在Git中跟踪它.有了README文件,就Git而言,目录不再是空的.

真正的问题是为什么你需要git中的空目录?通常你有一些构建脚本可以在编译/运行之前创建空目录.如果没有,那就做一个.这是一个比将空目录放在git中更好的解决方案.

所以你有理由在git中需要一个空目录.把这个原因放在README文件中.这样,其他开发人员(以及未来的你)知道为什么空目录需要在那里.您还将知道,当解决了需要空目录的问题时,您可以删除空目录.


要列出每个空目录,请使用以下命令:

find -name .git -prune -o -type d -empty -print
Run Code Online (Sandbox Code Playgroud)

要在每个空目录中创建占位符自述文件:

find -name .git -prune -o -type d -empty -exec sh -c \
  "echo this directory needs to be empty because reasons > {}/README.emptydir" \;
Run Code Online (Sandbox Code Playgroud)

要忽略除README文件之外的目录中的所有内容,请在以下行中添加以下行.gitignore:

path/to/emptydir/*
!path/to/emptydir/README.emptydir
path/to/otheremptydir/*
!path/to/otheremptydir/README.emptydir
Run Code Online (Sandbox Code Playgroud)

或者,您可以排除每个 README文件被忽略:

path/to/emptydir/*
path/to/otheremptydir/*
!README.emptydir
Run Code Online (Sandbox Code Playgroud)

要在每个README创建后列出它们:

find -name README.emptydir
Run Code Online (Sandbox Code Playgroud)


ofa*_*vre 27

警告:这个调整并没有真正发挥作用.抱歉给你带来不便.

原帖如下:

我在玩Git内部时找到了解决方案!

  1. 假设您在存储库中.
  2. 创建空目录:

    $ mkdir path/to/empty-folder
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用管道命令和空树SHA-1将其添加到索引:

    $ git update-index --index-info
    040000 tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904    path/to/empty-folder
    
    Run Code Online (Sandbox Code Playgroud)

    键入命令,然后输入第二行.按Enter,然后按Ctrl+ D以终止输入.注意:格式为模式 [SPACE] 类型 [SPACE] SHA-1hash [TAB]路径(选项卡很重要,答案格式不保留它).

  4. 而已!您的空文件夹位于索引中.你所要做的就是提交.

这个解决方案很短,显然工作正常(参见编辑!),但它并不容易记住......

空树SHA-1可以通过创建一个新的空Git存储库找到cd它并发出git write-tree,它输出空树SHA-1.

编辑:

自从我找到它以来,我一直在使用这个解决方案.它似乎与创建子模块的工作方式完全相同,只是在任何地方都没有定义模块.这会在发布时导致错误git submodule init|update.问题是git update-index040000 tree部分重写为160000 commit.

此外,放在该路径下的任何文件都不会被Git注意到,因为它认为它们属于某个其他存储库.这很讨厌,因为它很容易被忽视!

但是,如果您尚未(并且不会)在存储库中使用任何Git子模块,并且"empty"文件夹将保持为空或者您希望Git知道其存在并忽略其内容,则可以使用这个调整.以子模块的常规方式采取更多步骤进行调整.

  • 这种调整不太可能适用于任何其他工具.如警告和编辑中所述,除非在非常有限的情况下,否则我不鼓励使用它. (2认同)
  • 我基于此创建了一个更好的解决方案,没有这些缺点:/sf/answers/4098041181/ (2认同)

m10*_*104 20

假设您需要一个名为tmp的空目录:

$ mkdir tmp
$ touch tmp/.gitignore
$ git add tmp
$ echo '*' > tmp/.gitignore
$ git commit -m 'Empty directory' tmp
Run Code Online (Sandbox Code Playgroud)

换句话说,您需要将.gitignore文件添加到索引中,然后才能告诉Git忽略它(以及空目录中的其他所有内容).

  • 两件事:您可以"回显"*'> tmp/.gitignore而不是触摸,而"git commit -m"在您将文件添加到索引后不会提交更改. (11认同)
  • 如果你只是做`echo bla> file`你将不会得到`file:File exists`因为`>`会覆盖文件,如果它已经存在,或者如果它不存在则创建一个新文件. (6认同)
  • `/ bin/sh`文化假设!*如果"here"是`csh`并且设置了变量`noclobber`,你确实会得到`file:File exists`.如果有人说"我得到了这个",不要以为他们是个白痴并回答"不,你不这样做".*http://c2.com/cgi/wiki?AmericanCulturalAssumption (3认同)
  • @SeldomNeedy也许他们正在寻求帮助,因为他们甚至不知道他们使用的是不同于其他人的shell. (2认同)

nob*_*bar 20

也许添加一个空目录似乎是阻力最小路径,因为你有脚本期望该目录存在(可能因为它是生成二进制文件的目标).另一种方法是修改脚本以根据需要创建目录.

mkdir --parents .generated/bin ## create a folder for storing generated binaries
mv myprogram1 myprogram2 .generated/bin ## populate the directory as needed
Run Code Online (Sandbox Code Playgroud)

在此示例中,您可以检入目录的(损坏的)符号链接,以便您可以在不使用".generated"前缀的情况下访问它(但这是可选的).

ln -sf .generated/bin bin
git add bin
Run Code Online (Sandbox Code Playgroud)

当您想要清理源树时,您可以:

rm -rf .generated ## this should be in a "clean" script or in a makefile
Run Code Online (Sandbox Code Playgroud)

如果您采用经常建议的方法来检查几乎为空的文件夹,则删除内容的复杂性很小,而不会删除".gitignore"文件.

您可以通过将以下内容添加到根.gitignore来忽略所有生成的文件:

.generated
Run Code Online (Sandbox Code Playgroud)

  • 我同意,在某些情况下,这是一个很好的主意,但在其他情况下(例如,分发一个项目,在该项目中您拥有一个空的框架,其中包含诸如model /和views /的文件夹),您希望用户拥有这些目录,而不是无需手动阅读文档,而期望他们在克隆存储库后运行某种安装脚本可能会有点困难。我认为这个答案与@ john-mee的README答案相结合应该涵盖大多数(即使不是全部)情况。 (2认同)

小智 14

我也一直面临空目录的问题.使用占位符文件的问题是你需要创建它们,并删除它们,如果不再需要它们(因为后来有添加的子目录或文件.使用大源树管理这些占位符文件可能很麻烦和错误易于.

这就是为什么我决定编写一个开源工具,可以自动管理这些占位符文件的创建/删除.它是为.NET平台编写的,可在Mono(.NET for Linux)和Windows下运行.

请查看:http://code.google.com/p/markemptydirs


Mig*_*g82 14

我喜欢@ Artur79和@mjs的答案,所以我一直在使用两者的组合,并使其成为我们项目的标准.

find . -type d -empty -exec touch {}/.gitkeep \;
Run Code Online (Sandbox Code Playgroud)

但是,只有少数开发人员在Mac或Linux上工作.在Windows上做了很多工作,我找不到相同的简单单行程来完成相同的工作.有些人幸运的是因为其他原因安装了Cygwin,但是为此而开的Cygwin处方看起来有些过分.

编辑以获得更好的解决方案

因此,由于我们的大多数开发人员已经安装了Ant,我首先想到的是将Ant构建文件组合在一起,以独立于平台完成此任务.这仍然可以在这里找到

但是,我后来认为将它变成一个小的实用程序命令会更好,所以我使用Python重新创建它并在此处将它发布到PyPI .您只需运行以下命令即可安装:

pip3 install gitkeep2
Run Code Online (Sandbox Code Playgroud)

它允许您以.gitkeep递归方式创建和删除文件,并且还允许您向对等方添加消息,以便了解这些目录的重要性.最后一点是奖金.我认为如果.gitkeep文件可以自我记录会很好.

$ gitkeep --help
Usage: gitkeep [OPTIONS] PATH

  Add a .gitkeep file to a directory in order to push them into a Git repo
  even if they're empty.

  Read more about why this is necessary at: https://git.wiki.kernel.org/inde
  x.php/Git_FAQ#Can_I_add_empty_directories.3F

Options:
  -r, --recursive     Add or remove the .gitkeep files recursively for all
                      sub-directories in the specified path.
  -l, --let-go        Remove the .gitkeep files from the specified path.
  -e, --empty         Create empty .gitkeep files. This will ignore any
                      message provided
  -m, --message TEXT  A message to be included in the .gitkeep file, ideally
                      used to explain why it's important to push the specified
                      directory to source control even if it's empty.
  -v, --verbose       Print out everything.
  --help              Show this message and exit.
Run Code Online (Sandbox Code Playgroud)

希望对你有帮助.


小智 12

你不能,不幸的是永远不会.这是Linus Torvald本人做出的决定.他知道什么对我们有好处.

在那里我读过一次咆哮.

我找到了Re:Empty目录..但也许还有另一个.

你不得不忍受变通办法......不幸的是.

  • 我知道您将此作为一个错误论证的示例发布,但我很欣赏这个链接,因为它实际上是反对跟踪目录的合理论证。;-) (2认同)
  • 这个答案似乎不一致,因为在引用线程的下一篇文章中,Linus Torvald 说他希望他们需要添加目录跟踪:http://markmail.org/message/libip4vpvvxhyqbl。事实上,他说他“欢迎[添加对跟踪空目录的支持]的补丁” (2认同)

ntn*_*nja 11

阅读@ofavre@stanislav-bashkyrtsev的答案,使用损坏的 GIT 子模块引用来创建 GIT 目录,我很惊讶没有人建议对这个想法进行这种简单的修改,以使整个事情变得理智和安全:

与其将一个虚假的子模块破解到 GIT 中,不如添加一个空的真实子模块

输入:https : //gitlab.com/empty-repo/empty.git

一个只有一次提交的 GIT 存储库:

commit e84d7b81f0033399e325b8037ed2b801a5c994e0
Author: Nobody <none>
Date: Thu Jan 1 00:00:00 1970 +0000
Run Code Online (Sandbox Code Playgroud)

没有消息,没有提交的文件。

用法

向您的 GIT 存储库添加一个空目录:

commit e84d7b81f0033399e325b8037ed2b801a5c994e0
Author: Nobody <none>
Date: Thu Jan 1 00:00:00 1970 +0000
Run Code Online (Sandbox Code Playgroud)

将所有现有的空目录转换为子模块:

git submodule add https://gitlab.com/empty-repo/empty.git path/to/dir
Run Code Online (Sandbox Code Playgroud)

Git 会在创建子模块引用时存储最新的提交哈希,因此您不必担心我(或 GitLab)使用它来注入恶意文件。不幸的是,我还没有找到任何方法来强制在结帐期间使用哪个提交 ID,因此您必须在添加 repo 后手动检查参考提交 ID 是否正在e84d7b81f0033399e325b8037ed2b801a5c994e0使用git submodule status

仍然不是本机解决方案,但是我们可能拥有的最好的解决方案,而无需有人在 GIT 代码库中真正非常脏。

附录:重新创建此提交

您应该能够使用(在空目录中)重新创建这个确切的提交:

find . -type d -empty -delete -exec git submodule add -f https://gitlab.com/empty-repo/empty.git \{\} \;
Run Code Online (Sandbox Code Playgroud)

创建可重现的 GIT 提交非常困难……


Mic*_*son 10

当你添加一个.gitignore文件时,如果要在其中放入任何数量的内容(你希望Git忽略它),你可能想要添加一行只带一个星号*,以确保你不会意外添加被忽略的内容.


Pet*_*oeg 8

如上所述,不可能添加空目录,但这里有一个将空.gitignore文件添加到所有目录的单行程序.

ruby -e 'require "fileutils" ; Dir.glob(["target_directory","target_directory/**"]).each { |f| FileUtils.touch(File.join(f, ".gitignore")) if File.directory?(f) }'

我把它放在Rakefile中以便于访问.

  • 我宁愿用`find.-type d -empty -print0 | xargs --null bash -c'代表; 做{echo"*"; echo"!.gitignore"; } >>"$ a/.gitignore"; 完成' - (6认同)

Rom*_*man 8

Jamie Flournoy的解决方案效果很好.这是一个有点增强版本,以保持.htaccess:

# Ignore everything in this directory
*
# Except this file
!.gitignore
!.htaccess
Run Code Online (Sandbox Code Playgroud)

使用此解决方案,您可以提交一个空文件夹,例如/log,/tmp或者/cache该文件夹将保持为空.

  • 他想保留一个空目录而不是文件. (2认同)
  • 而且我已经提到它也会保留.htaccess.示例:如果软件具有不应通过Web访问的日志文件(如氧化eshop)目录,则目录中存在.htaccess.如果你将上面提到的.gitignore放在文件夹中,.htaccess将不会被调用,文件夹将可以通过web访问. (2认同)

Zaz*_*Zaz 8

没有办法让Git跟踪目录,所以唯一的解决方案是在你希望Git跟踪的目录中添加一个占位符文件.

该文件可以命名并包含您想要的任何内容,但大多数人使用一个名为空的文件.gitkeep(尽管有些人更喜欢VCS不可知.keep).

前缀将其.标记为隐藏文件.

另一个想法是添加一个README文件,解释目录将用于什么.


Dev*_*hon 8

这个解决方案对我有用。

1. 添加一个.gitignore文件到你的空目录:

*
*/
!.gitignore
Run Code Online (Sandbox Code Playgroud)
  • * 忽略文件夹中的所有文件
  • */ 忽略子目录
  • !.gitignore 包含 .gitignore 文件

2. 然后移除缓存,暂存文件,提交并推送:

git rm -r --cached .
git add . // or git stage .
git commit -m ".gitignore fix"
git push
Run Code Online (Sandbox Code Playgroud)


Mil*_*uzz 7

我总是构建一个函数来检查我想要的文件夹结构,并在项目中为我构建它.这解决了这个问题,因为空文件夹由代理保存在Git中.

function check_page_custom_folder_structure () {
    if (!is_dir(TEMPLATEPATH."/page-customs"))
        mkdir(TEMPLATEPATH."/page-customs");    
    if (!is_dir(TEMPLATEPATH."/page-customs/css"))
        mkdir(TEMPLATEPATH."/page-customs/css");
    if (!is_dir(TEMPLATEPATH."/page-customs/js"))
        mkdir(TEMPLATEPATH."/page-customs/js");
}
Run Code Online (Sandbox Code Playgroud)

这是在PHP中,但我确信大多数语言都支持相同的功能,并且由于应用程序负责创建文件夹,因此文件夹将始终存在.

  • 所以我们都在同一页上,我不再这样做了.这是浪费时间.`.gitkeep`惯例是一个更好的做法. (2认同)

Sta*_*sev 7

这是一个黑客,但它很有趣(Git 2.2.1).与@Teka建议的类似,但更容易记住:

  • 将子模块添加到任何存储库(git submodule add path_to_repo)
  • 这将添加一个文件夹和一个文件.submodules.做出改变.
  • 删除.submodules文件并提交更改.

现在,您有一个在签出提交时创建的目录.一个有趣的事情是,如果你看看这个文件的树对象的内容,你会得到:

致命的:不是有效的对象名称b64338b90b4209263b50244d18278c0999867193

我不鼓励使用它,因为它可能会停止在Git的未来版本中工作.这可能会使您的存储库损坏.

  • 一个**致命**黑客. (3认同)

Tre*_*her 6

有时您必须处理写得不好的库或软件,它们需要一个“真正的”空的和现有的目录。把一个简单的.gitignore.keep可能会破坏它们并导致错误。在这些情况下,以下内容可能会有所帮助,但不能保证......

首先创建需要的目录:

mkdir empty
Run Code Online (Sandbox Code Playgroud)

然后向该目录添加一个损坏的符号链接(但在上述用例之外的任何其他情况下,请使用README带有解释的 a):

ln -s .this.directory empty/.keep
Run Code Online (Sandbox Code Playgroud)

要忽略此目录中的文件,您可以将其添加到您的根目录中.gitignore

echo "/empty" >> .gitignore
Run Code Online (Sandbox Code Playgroud)

要添加被忽略的文件,请使用一个参数来强制它:

git add -f empty/.keep
Run Code Online (Sandbox Code Playgroud)

提交后,您的索引中有一个损坏的符号链接,git 会创建该目录。断开的链接有一些优点,因为它不是常规文件并且指向非常规文件。所以它甚至适合问题“(不包含文件)”的一部分,不是意图而是意义,我猜:

find empty -type f
Run Code Online (Sandbox Code Playgroud)

此命令显示空结果,因为此目录中不存在文件。因此,大多数获取目录中所有文件的应用程序通常看不到此链接,至少在它们执行“文件存在”或“可读”的情况下。甚至有些脚本在那里也找不到任何文件:

$ php -r "var_export(glob('empty/.*'));"
array (
  0 => 'empty/.',
  1 => 'empty/..',
)
Run Code Online (Sandbox Code Playgroud)

但是我强烈建议只在特殊情况下使用这个解决方案,一个好的写README在一个空目录中通常是一个更好的解决方案。(我不知道这是否适用于 Windows 文件系统......)


ajm*_*way 6

如果你想在多个语义目录中添加一个容纳大量瞬态数据的文件夹,那么一种方法是在你的root .gitignore中添加这样的东西......

/app/data/**/*.* !/app/data/**/*.md

然后,您可以*.md在每个目录中提交描述性README.md文件(或空白文件,无关紧要,只要您可以像在本例中那样唯一地定位它们),以确保目录全部保留在repo的一部分但是文件(带扩展名)将被忽略.限制:.目录名称中不允许使用!

您可以使用xml/images文件或其他任何内容填充所有这些目录,并/app/data/随着时间的推移添加更多目录,因为您的应用程序需要开发存储(使用README.md文件来描述每个存储目录的用途)究竟).

没有必要.gitignore通过.gitignore为每个新目录创建一个新的来进一步改变或分散.可能不是最聪明的解决方案,但是简洁明了,总是适合我.好又简单!;)

在此输入图像描述


Hai*_*n.Z 6

许多人已经回答了这个问题。只需在此处添加PowerShell版本。

在目录中找到所有空文件夹

在其中添加一个空的.gitkeep文件

Get-ChildItem 'Path to your Folder' -Recurse -Directory | Where-Object {[System.IO.Directory]::GetFileSystemEntries($_.FullName).Count -eq 0} | ForEach-Object { New-Item ($_.FullName + "\.gitkeep") -ItemType file}
Run Code Online (Sandbox Code Playgroud)


Jör*_*tag 5

你不能 这是Git维护者的有意设计决定。基本上,像Git这样的源代码管理系统的目的是管理源代码,而空目录不是源代码。Git通常也被描述为内容跟踪器,同样,空目录也不是内容(实际上恰恰相反),因此它们不会被跟踪。

  • 我反对这种观点。**结构**就是内容,而您**名字**的所有内容都有助于内容。 (56认同)
  • 空文件也不是源代码或内容。这只是一个名字。但是,Git会愉快地跟踪空文件。我认为让Git拒绝跟踪空目录不是故意的设计决定。我认为跟踪空目录是一项功能,在99%的时间中根本不需要,因此他们不必费心去做使其正常工作所需的额外工作。如果有人非常想实现该功能,Git可以做到。我怀疑如果正确完成Git维护者会反对这样的补丁。 (18认同)
  • 这是一项缺少的功能(优先级较低),不是故意的限制。来自Git常见问题解答:目前,Git索引(临时区域)的设计仅允许列出文件,并且**没有足够的能力来进行更改以允许空目录的人对此情况已经足够在意,以进行补救。 (3认同)

Mik*_*ike 5

再增加一个选项。

假设您想向其中添加一个目录git,出于与 相关的所有目的git,应保持为空,并且永远不会跟踪其内容,.gitignore正如此处多次建议的那样,可以解决问题。

如前所述,格式是:

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

现在,如果你想有一个办法做到这一点在命令行中,一举,而里面的目录要添加,你可以执行:

$ echo "*" > .gitignore && echo '!.gitignore' >> .gitignore && git add .gitignore
Run Code Online (Sandbox Code Playgroud)

我自己有一个用于执行此操作的 shell 脚本。随意命名脚本,然后将其添加到包含路径中的某个位置,或直接引用它:

#!/bin/bash

dir=''

if [ "$1" != "" ]; then
    dir="$1/"
fi

echo "*" > $dir.gitignore && \
echo '!.gitignore' >> $dir.gitignore && \
git add $dir.gitignore
Run Code Online (Sandbox Code Playgroud)

有了这个,你可以从你想要添加的目录中执行它,或者引用该目录作为它的第一个也是唯一的参数:

$ ignore_dir ./some/directory
Run Code Online (Sandbox Code Playgroud)

另一种选择(响应由@GreenAsJade评论),如果你想跟踪一个空文件夹是MAY包含跟踪文件在未来,但将是空的,现在,你可以ommit的*.gitignore文件,并检查英寸基本上,所有文件都在说“不要忽略”,否则,该目录为空并被跟踪。

您的.gitignore文件将如下所示:

!.gitignore
Run Code Online (Sandbox Code Playgroud)

就是这样,检查它,您将拥有一个空的但已跟踪的目录,您可以稍后在其中跟踪文件。

我建议在文件中保留这一行的原因是它给出了.gitignore目的。否则,某些人可能会考虑将其删除。如果您在该行上方放置注释可能会有所帮助。


arc*_*don 5

一种简单的方法是将.gitkeep文件添加到您希望(当前)保持空白的目录中。

请参阅此SOF答案以获取更多信息-这也解释了为什么有些人发现添加.gitignore文件的竞争惯例(如此处许多答案所述)令人困惑。