How do I add an empty directory to a git repository
36
How do I convince git that I really do want an empty directory?
improve this question | comment
Russell Hane Created at: 2013-11-13 17:07:09 UTC By Russell Hane
While it's not useful, there is a way to hack an empty (really empty) directory into your repo. It won't checkout with current versions of Git, however. - Princess Oberbrunner
'it's not useful', in your opinion only, tiwo. that doesn't make it true. - Nasir Mraz
@tiwo I for one disagree that it's not useful. Your directory hierarchy is part of your project, so it should be version controlled. - Kenya Mayer DVM
In my case, I'd like to add a directory structure for tmp files, but not the tmp files themselves.
By doing this, my tester has the correct structure (otherwise there are errors) but I don't clog my commits with tmp data.
So yes, it's useful to me! - Gaetano Steuber
@AdamMarshall I think tiwo was saying that the hack is not useful, since it is ignored by checkout. Tmp dirs do sound like a useful feature for a VCS. - Loyce Kozey V
17 Answers
0
You can't. This is an intentional design decision by the Git maintainers. Basically, the purpose of a Source Code Management System like Git is managing source code and empty directories aren't source code. Git is also often described as a content tracker, and again, empty directories aren't content (quite the opposite, actually), so they are not tracked.
0
WARNING: This tweak is not truly working as it turns out. Sorry for the inconvenience.

Original post below:

I found a solution while playing with git internals!

Suppose you are in your repository.
Create your empty directory:

$ mkdir path/to/empty-folder

Add it to the index using a plumbing command and the empty tree SHA1:

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


Type the command then enter the second line, press enter then Ctrl+D to terminate your input.
Note: the format is mode [SPACE] type [SPACE] sha1hash [TAB] path (the tab is important, the answer formatting does not preserve it).
That's it! Your empty folder is in your index. All you have to do is commit.
This solution is short, works apparently fine (see the EDIT!), but is not that easy to remember...

The empty tree sha1 can be found by creating a new empty git repository, cd into it and issue git write-tree, which outputs the empty tree sha1.

EDIT:

I've been using this solution since I found it. It appears to work exactly the same way as creating a submodule, except that no module is defined anywhere.
This leads to errors when issuing git submodule init|update.
The problem is that git update-index rewrites the 040000 tree part into 160000 commit.

Moreover, any file placed under that path won't ever be noticed by git, as it thinks they belong to some other repository. This is nasty as it can easily be overlooked!

However, if you don't already (and won't) use any git submodules in your repository, and the "empty" folder will remain empty or if you want git to know of its existence and ignore its content, you can go with this tweak. Going the usual way with submodules takes more steps that this tweak.
0
You could always put a README file in the directory with an explanation of why you want this, otherwise empty, directory in the repository.
0
As described in other answers, git is unable to represent empty directories in its staging area.  (See the git FAQ.)  However, if, for your purposes, a directory is empty enough if it contains a .gitignore file only, then you can create .gitignore files in empty directories only via:

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

0
Create an empty file called .gitkeep in the directory, and add that.
0
Andy Lester is right, but if your directory just needs to be empty, and not empty empty, you can put an empty .gitignore file in there as a workaround.

As an aside, this is an implementation issue, not a fundamental git storage design problem. As has been mentioned many times on the git mailing list, the reason that this has not been implemented is that no one has cared enough to submit a patch for it, not that it couldn’t or shouldn’t be done.
0
The Rails Way :

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


Now the log dir will be included in the tree, super-useful when deploying, so you won't have to write a routine to make log dirs.

The logfiles can be kept out by issuing, 

echo log/dev.log >> .gitignore


but you probably knew that
0
I always build a function to check for my desired folder structure and build it for me within the project, this get's around this problem as the empty folders are held in git by proxy

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");
}


This is in PHP, but I am sure most languages support the same functionality, and because the creation of the folders is taken care of by the application, the folders will always be there.
0
You can't.  See the Git FAQ.


  Currently the design of the git index
  (staging area) only permits files to
  be listed, and nobody competent enough
  to make the change to allow empty
  directories has cared enough about
  this situation to remedy it.
  
  Directories are added automatically
  when adding files inside them. That
  is, directories never have to be added
  to the repository, and are not tracked
  on their own.
  
  You can say "git add <dir>" and it
  will add files in there.
  
  If you really need a directory to
  exist in checkouts you should create a
  file in it. .gitignore works well for
  this purpose; you can leave it empty,
  or fill in the names of files you
  expect to show up in the directory.

0
Maybe adding an empty directory seems like it would be the path of least resistance because you have scripts that expect that directory to exist (maybe because it is a target for generated binaries).  Another approach would be to modify your scripts to create the directory as needed.

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


In this example, you might check in a (broken) symbolic link to the directory so that you can access it without the ".generated" prefix (but this is optional).

ln -sf .generated/bin bin
git add bin


When you want to clean up your source tree you can just:

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


If you take the oft-suggested approach of checking in an almost-empty folder, you have the minor complexity of deleting the contents without also deleting the ".gitignore" file.

You can ignore all of your generated files by adding the following to your root .gitignore:

.generated

0
I've been facing the issue with empty directories, too. The problem with using placeholder files is that you need to create them, and delete them, if they are not necessary anymore (because later on there were added sub-directories or files. With big source trees managing these placeholder files can be cumbersome and error prone.

This is why I decided to write an open source tool which can manage the creation/deletion of such placeholder files automatically. It is written for .NET platform and runs under Mono (.NET for Linux) and Windows.

Just have a look at: http://code.google.com/p/markemptydirs

Best regards and have fun with it :)

Jonny Dee
0
When you add a .gitignore file, if you are going to put any amount of content in it (that you want git to ignore) you might want to add a single line with just an asterisk (*) to make sure you don't add the ignored content accidentally.
0
Let's say you need an empty directory named tmp:

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


In other words, you need to add the .gitignore file to the index before you can tell Git to ignore it (and everything else in the empty directory).
0
Put a README file in the empty directory explaining why the directory is empty. As far as git is concerned, the directory is no longer empty.

To list every empty directory use the following command:

find -not -path "*/.git/*" -type d -empty


To create placeholder READMEs in every empty directory:

find -not -path "*/.git/*" -type d -empty -exec sh -c "echo this directory is intentionally left empty > {}/README.emptydir" \;


To ignore everything in the directory except the README file put the following lines in your .gitignore:

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


Alternatively, you could just exclude every README file from being ignored:

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


Note: the exclude line must be placed after the ignore line.

Background:

Git does not track empty directories, as stated by @Andy Lester. The suggested workaround is to put a .gitignore file in the empty directory. @Jamie Flournoy refined the idea to ignore everything except for the .gitignore file itself. I do not like this solution because there are "ignore everything"-rules scattered all over the place. Also there is no explanation why the directories are empty.

The idea to put a README file in the empty directory was suggested by @John Mee.
0
As mentioned it's not possible to add empty directories, but here is a one liner that adds empty .gitignore files to all directories.

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

I have stuck this in a Rakefile for easy access.
0
You can save this code as create_readme.php and run the php code from the root directory of your git project.

> php create_readme.php


It will add README files to all directories that are empty so those directories would be then added to the index. 

<?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
        }
    }
?>


Then do 

git commit -m "message"
git push

0
Another way to make a directory stay empty (in the repo) is to create a .gitignore file inside that directory that contains four lines:

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


Then you don't have to get the order right the way that you have to do in m104's solution.
Your Answer