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

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

答案

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

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

这样一来,您就不必像 m104 解决方案中那样正确地获得订单。

这也带来了好处,当您执行 git 状态时,该目录中的文件不会显示为 “未跟踪”。

使@GreenAsJade的评论持续存在:

我认为值得一提的是,该解决方案恰好满足了该问题的要求,但也许并不是很多关注此问题的人一直在寻找。此解决方案确保目录保持为空。它说:“我真的不希望在这里签入文件”。与 “我还没有任何文件可以在这里签入,但是我需要在这里的目录,文件可能稍后再来” 相反。

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

当前,git 索引(临时区域)的设计仅允许列出文件,并且没有足够的能力来进行更改以允许空目录的人已经足够在意这种情况以进行纠正。

在目录中添加文件时会自动添加目录。也就是说,目录永远不必添加到存储库,也不需要单独跟踪。

您可以说 “ git add <dir> ”,它将在其中添加文件。

如果您确实需要在结帐中存在目录,则应在其中创建一个文件。 .gitignore 为此很好地工作;您可以将其保留为空,或填写您希望在目录中显示的文件名。

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

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

touch .keep

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

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

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

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

第一件事:

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

它根本不会被跟踪。但是在某些情况下,“版本化” 空目录可能很有意义,例如:

  • 搭建预定义的文件夹结构 ,使其可用于存储库的每个用户 / 贡献者;或者,作为上述的一种特殊情况,我们为临时文件 (例如cache/logs/目录)创建一个文件夹,我们要在其中提供该文件夹,但是.gitignore它的内容
  • 与此相关的是,某些项目如果没有某些文件夹将无法工作 (这通常是项目设计不佳的提示,但这是一个经常在现实世界中出现的场景,也许可能会解决权限问题)。

一些建议的解决方法

许多用户建议:

  1. README文件或其他文件放入某些内容,以使目录为非空,或者
  2. 创建具有某种 “逆向逻辑”(即包括所有文件)的.gitignore文件,最后,该方法具有与方法 1 相同的目的。

虽然这两种解决方案都能正常工作,但我发现它们与有意义的 Git 版本控制方法不一致。

  • 为什么要在项目中放入您可能不需要的伪造文件或自述文件?
  • 即使可能,为什么还要使用.gitignore做某事( 保留文件)却与它的意图( 排除文件)相反呢?

.gitkeep 方法

使用一个名为.gitkeep文件,以强制该文件夹存在于版本控制系统中。

尽管看起来差别不大:

  • 您可以使用具有保持文件夹的单一用途的文件。您不会在此处放置任何您不想放置的信息。

    例如,您应该使用自述文件以及具有有用信息的自述文件,而不是保留文件夹的借口。

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

  • 将其命名为.gitkeep可以使文件名本身(以及其他开发人员)非常清楚,直接,这对于共享项目和 Git 存储库的核心目的之一都非常有用,即该文件是

    • 与代码无关的文件(由于前导点和名称)
    • 与 Git 明确相关的文件
    • 它的目的( keep )清楚地说明了,并且在含义上是一致的并且在语义上是对立的,可以忽略

采用

我已经看到非常重要的框架(例如LaravelAngular-CLI)采用了.gitkeep方法。

如其他答案所述,Git 无法在其暂存区域中表示空目录。 (请参阅Git 常见问题解答 。)但是,如果出于您的目的,如果目录仅包含.gitignore文件,则该目录足够空,则只能通过以下方式在空目录中创建.gitignore文件:

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

安迪 · 莱斯特(Andy Lester)是对的,但是如果您的目录只需要为空,而不是目录,则可以在其中放置一个空的.gitignore文件作为解决方法。

顺便说一句,这是一个实现问题,而不是基本的 Git 存储设计问题。正如在 Git 邮件列表中多次提到的那样,未实现此问题的原因是,没有人愿意为此提交补丁,而不是无法或不应该这样做。

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

mkdir log && touch log/.gitkeep && git add log/.gitkeep

现在,日志目录将包含在树中。部署时它非常有用,因此您无需编写例程即可创建日志目录。

可以通过发出以下命令来保留日志文件:

echo log/dev.log >> .gitignore

但您可能知道这一点。

Git 不会跟踪空目录。有关更多说明,请参见Git FAQ 。建议的解决方法是将.gitignore文件放在空目录中。我不喜欢这种解决方案,因为.gitignore被 Unix 约定 “隐藏”。也没有解释为什么目录为空。

我建议将 README 文件放在空目录中,解释为什么该目录为空以及为什么需要在 Git 中对其进行跟踪。就 README 文件而言,就 Git 而言,该目录不再为空。

真正的问题是,为什么在 git 中需要空目录?通常,您具有某种构建脚本,可以在编译 / 运行之前创建空目录。如果没有,那就做一个。这比将空目录放入 git 更好。

因此,您有某些原因为什么需要在 git 中使用一个空目录。将该原因放在自述文件中。这样,其他开发人员(以及您将来的开发人员)就会知道为什么需要存在空目录。您还将知道,当解决了要求空目录的问题后,就可以删除空目录。


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

find -name .git -prune -o -type d -empty -print

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

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

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

path/to/emptydir/*
!path/to/emptydir/README.emptydir
path/to/otheremptydir/*
!path/to/otheremptydir/README.emptydir

另外,您可以排除每个自述文件而忽略它们:

path/to/emptydir/*
path/to/otheremptydir/*
!README.emptydir

在创建每个自述文件后列出它们:

find -name README.emptydir