我怎么可以添加一个空的目录(不包含任何文件)以个混库?

有帮助吗?

解决方案

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

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

然后,您无需按照m104的解决方案中的方式完成订单。

这也带来了以下好处:该目录中的文件不会显示为<!> quot; untracked <!> quot;当你做一个git状态时。

使 @GreenAsJade 的评论持久:

  

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

其他提示

你做不到。请参阅 Git常见问题解答

  

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

     

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

     

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

     

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

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

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

touch .keep

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

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

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

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

首先第一件事情:

一个空的目录 不可能是部分的一棵树下从初版本控制系统.

它根本不会被跟踪。但在有些情况下在其"版本控制的"空目录可以有意义的,例如:

  • 一个脚手架 预先定义的文件夹结构, ,使它可为每一个用户/遣国的存储库;或者,作为一个专门的情况下以上时,创建一个文件夹 临时文件, 如一 cache/logs/ 目录,其中我们想要提供的文件夹,但 .gitignore 它的内容
  • 有关上述,一些项目 不会工作如果没有一些文件夹 (这往往是一个暗示的设计不当的项目,但它是一个经常现实世界的情景,也许有可能是,比如说,权限的问题加以解决).

一些建议的解决方法

许多用户的建议:

  1. 把一个 README 文件或其他文件的一些内容,以便使目录非空,或
  2. 创建一个 .gitignore 文件有一种"反向逻辑"(即包括所有的文件),结束时,服务于同一目的的方法#1.

同时 这两个解决方案当然的工作 我发现它们不符合一个有意义的方式件版本控制。

  • 为什么你应该把伪造文件或者自述,也许你不是真想在你的的项目呢?
  • 为什么使用 .gitignore 要做的事情(保持 文件),是非常相反的是什么意思(不包括 文件),虽然它是可能的吗?

.gitkeep的方法

使用 文件称为 .gitkeep 为了力的存在文件夹中的版本控制系统。

虽然它可能似乎没有这么大的差别:

  • 你使用一个文件 目的保持的文件夹。你不要放在那里的任何信息,你不想放。

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

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

  • 它命名 .gitkeep 使得它非常明确和直接从该文件本身(而且也 其他开发商, ,这是很好的一个共同项目和的一个核心目的的个混库),该文件

    • 一个文件无关的代码(因为领先点和名称)
    • 文件明确相关件
    • 其目(保持)是清楚的说明和一致和在语义上相对于其含义 忽略

通过

我已经看到的 .gitkeep 采用的方法非常重要的框架喜欢 Laravel, 角CLI.

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

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

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

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

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

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

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

可以通过发出

来阻止日志文件
echo log/dev.log >> .gitignore

但你可能知道。

Git不会跟踪空目录。有关更多说明,请参阅 Git常见问题解答。建议的解决方法是将.gitignore文件放在空目录中。我不喜欢这个解决方案,因为<=>是<!>“隐藏<!>”;通过Unix惯例。也没有解释为什么目录是空的。

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

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

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


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

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文件之外的目录中的所有内容,请在<=>:

中添加以下行
path/to/emptydir/*
!path/to/emptydir/README.emptydir
path/to/otheremptydir/*
!path/to/otheremptydir/README.emptydir

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

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

列出每个自述文件后的每个自述文件:

find -name README.emptydir

警告:此调整并非真正有效。很抱歉给您带来不便。

以下原帖:

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

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

    $ mkdir path/to/empty-folder
    
  3. 使用管道命令和空树 SHA-1 <将其添加到索引中/一个>:

    $ git update-index --index-info
    040000 tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904    path/to/empty-folder
    

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

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

  5. 此解决方案很短,显然效果很好(参见编辑!),但这并不容易记住......

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

    修改

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

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

    但是,如果您还没有(并且不会)在您的存储库中使用任何Git子模块,并且<!> quot; empty <!>;文件夹将保持为空或如果您希望Git知道它的存在并忽略其内容,您可以使用此调整。按照惯常的方式使用子模块需要采取更多步骤进行调整。

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

mkdir --parents .generated/bin ## create a folder for storing generated binaries
mv myprogram1 myprogram2 .generated/bin ## populate the directory as needed

在此示例中,您可以检入目录的(损坏的)符号链接,以便在没有<!> quot; .generated <!>的情况下访问它;前缀(但这是可选的)。

ln -sf .generated/bin bin
git add bin

如果要清理源树,可以:

rm -rf .generated ## this should be in a "clean" script or in a makefile

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

您可以通过将以下内容添加到根.gitignore:

来忽略所有生成的文件
.generated

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

$ mkdir tmp
$ touch tmp/.gitignore
$ git add tmp
$ echo '*' > tmp/.gitignore
$ git commit -m 'Empty directory' tmp

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

你不能也不可能永远无法做到。这是Linus Torvald本人做出的决定。他知道什么对我们有好处。

在那里我读过一次咆哮。

我找到 Re:空目录...... ,但也许有另一个。

不幸的是,你必须忍受变通办法。

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

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

但是,只有少数开发人员在Mac或Linux上工作。在Windows上做了很多工作,我找不到相同的简单单行程来完成相同的工作。有些人幸运的是因为其他原因安装了 Cygwin ,但是为此而开的Cygwin似乎有点矫枉过正。

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

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

然而,我后来认为将它变成一个小实用程序命令会更好,所以我使用Python重新创建它并将其发布到PyPI 这里。您只需运行以下命令即可安装:

pip3 install gitkeep2

它允许您递归地创建和删除.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.

我希望你觉得它很有用。

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

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

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

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

Jamie Flournoy的解决方案效果很好。这是一个保持.htaccess

的增强版本
# Ignore everything in this directory
*
# Except this file
!.gitignore
!.htaccess

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

我总是构建一个函数来检查我想要的文件夹结构,并在项目中为我构建它。这解决了这个问题,因为空文件夹由代理保存在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");
}

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

这里是一个黑客,但它很有趣,它的工作(Git2.2.1).类似什么@特卡建议,但更容易记住:

  • 增加一个子模块的任何库(git submodule add path_to_repo)
  • 这将增加一个文件夹和一个文件 .submodules.提交的变化。
  • 删除 .submodules 文件和提交的变化。

现在,你有一个目录,得到创造当提交被检查出来。一个有趣的事情但是如果你看一下内容的树目的这个文件,你会得到:

致命的:没有一个有效的对象的名字 b64338b90b4209263b50244d18278c0999867193

我不鼓励使用它,虽然因为它可能会停止工作,在未来版本的饭桶。这可能会离开你的仓库损坏。

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

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

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

另一个想法是添加一个README文件,解释目录的用途。

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

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

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

然后你可以在每个目录中提交描述性的README.md文件(或空白文件,无关紧要,只要你可以像在这种情况下那样唯一地定位它们),以确保所有目录都保留repo的一部分,但文件(带扩展名)将被忽略。限制:目录名称中不允许*.md

您可以使用xml / images文件或其他任何内容填充所有这些目录,并随着时间的推移在.下添加更多目录,因为您的应用程序的存储需求正在开发中(README.md文件用于描述每个存储目录的确切含义。

通过为每个新目录创建新的/app/data/,无需进一步更改.gitignore或分散。可能不是最聪明的解决方案,但是简洁明了,总是适合我。好又简单! ;)

为战斗添加一个选项。

假设您想要添加一个目录git,为了与.gitignore相关的所有目的,应该保持为空并且永远不会跟踪它的内容,这里建议多次*

如上所述,格式为:

*
!.gitignore

现在,如果你想在命令行中做一个方法,一下子, inside 你要添加的目录,你可以执行:

$ echo "*" > .gitignore && echo '!.gitignore' >> .gitignore && git add .gitignore

我自己,我有一个用于执行此操作的shell脚本。无论你想要什么,都要命名脚本,并将其添加到include路径中的某个位置,或者直接引用它:

#!/bin/bash

dir=''

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

echo "*" > $dir.gitignore && \
echo '!.gitignore' >> $dir.gitignore && \
git add $dir.gitignore

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

$ ignore_dir ./some/directory

另一个选项(响应@GreenAsJade的评论),如果你想跟踪一个 MAY 将来包含跟踪文件的空文件夹,但现在是空的,你可以省略来自<=>文件的<=>,并检查那个。基本上,所有文件都是<!>;不要忽略 me <!> “;否则,该目录为空并进行跟踪。

您的<=>文件如下所示:

!.gitignore

就是这样,检查一下,你有一个空的,但跟踪的目录,你可以在以后跟踪文件。

我建议在文件中保留一行的原因是它给出了<=>目的。否则,某些人可能会认为将其删除。如果您在该行上方发表评论可能会有所帮助。

有时你必须处理糟糕的书面库或软件,这需要一个<!> quot; real <!> quot;空和现有目录。使用简单的.gitignore.keep可能会破坏它们并导致错误。以下可能有助于这些情况,但不保证......

首先创建所需的目录:

mkdir empty

然后你向这个目录添加一个破损的符号链接(但除了上面描述的用例之外的任何其他情况,请使用带有解释的README):

ln -s .this.directory empty/.keep

要忽略此目录中的文件,可以将其添加到根<=>:

echo "/empty" >> .gitignore

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

git add -f empty/.keep

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

find empty -type f

此命令显示空结果,因为此目录中不存在任何文件。因此,获取目录中所有文件的大多数应用程序通常都看不到此链接,至少如果它们存在<!>“文件存在<!>”;或者<!>“是可读的<!>”;甚至一些脚本也找不到任何文件:

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

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

您可以将此代码保存为create_readme.php,并从根目录运行 PHP 代码你的Git项目。

> php create_readme.php

它会将README文件添加到所有空目录中,这样这些目录就会被添加到索引中。

<?php
    $path = realpath('.');
    $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path),       RecursiveIteratorIterator::SELF_FIRST);
    foreach($objects as $name => $object){
        if ( is_dir($name) && ! is_empty_folder($name) ){
            echo "$name\n" ;
            exec("touch ".$name."/"."README");
        }
    }

    function is_empty_folder($folder) {
        $files = opendir($folder);
        while ($file = readdir($files)) {
            if ($file != '.' && $file != '..')
                return true; // Not empty
            }
        }
?>

然后做

git commit -m "message"
git push

有时我的文件夹存储库只包含被认为是<!>的文件<!>内容<!> <!>#!>#8212;也就是说,它们不是我关心版本化的文件,并且因此永远不应该犯下。使用Git的.gitignore文件,您可以忽略整个目录。但有时候在回购中使用文件夹会有所帮助。这是满足这一需求的出色解决方案。

我过去所做的是在我的仓库的根目录下放一个.gitignore文件,然后排除文件夹,如下所示:

/app/some-folder-to-exclude
/another-folder-to-exclude/*

然而,这些文件夹不会成为回购的一部分。您可以在其中添加类似README文件的内容。但是,您必须告诉您的应用程序不要担心处理任何README文件。

如果您的应用依赖于那里的文件夹(虽然是空的),您只需将.gitignore文件添加到相关文件夹中,然后使用它来完成两个目标:

告诉Git文件夹中有一个文件,这使得Git将它添加到repo中。 告诉Git忽略此文件夹的内容,减去此文件本身。 这是放在空目录中的.gitignore文件:

*
!.gitignore

第一行(*)告诉Git忽略此目录中的所有内容。第二行告诉Git不要忽略.gitignore文件。您可以将此文件填充到要添加到存储库的每个空文件夹中。

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top