How can I add an empty directory (that contains no files) to a Git repository?
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 \;
An easy way to do this is by adding a .gitkeep
file to the directory you wish to (currently) keep empty.
See this SOF answer for further info - which also explains why some people find the competing convention of adding a .gitignore file (as stated in many answers here) confusing.
I like the answers by @Artur79 and @mjs so I've been using a combination of both and made it a standard for our projects.
find . -type d -empty -exec touch {}/.gitkeep \;
However, only a handful of our developers work on Mac or Linux. A lot work on Windows and I could not find an equivalent simple one-liner to accomplish the same there. Some were lucky enough to have Cygwin installed for other reasons, but prescribing Cygwin just for this seemed overkill.
Edit for a better solution
So, since most of our developers already have Ant installed, the first thing I thought of was to put together an Ant build file to accomplish this independently of the platform. This can still be found here
However, I later thought It would be better to make this into a small utility command, so I recreated it using Python and published it to the PyPI here. You can install it by simply running:
pip3 install gitkeep2
It will allow you to create and remove .gitkeep
files recursively, and it will also allow you to add messages to them for your peers to understand why those directories are important. This last bit is bonus. I thought it would be nice if the .gitkeep
files could be self-documenting.
$ 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.
I hope you find it useful.
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
There's no way to get Git to track directories, so the only solution is to add a placeholder file within the directory that you want Git to track.
The file can be named and contain anything you want, but most people use an empty file named .gitkeep
(although some people prefer the VCS-agnostic .keep
).
The prefixed .
marks it as a hidden file.
Another idea would be to add a README
file explaining what the directory will be used for.
Sometimes you have to deal with bad written libraries or software, which need a "real" empty and existing directory. Putting a simple .gitignore
or .keep
might break them and cause a bug. The following might help in these cases, but no guarantee...
First create the needed directory:
mkdir empty
Then you add a broken symbolic link to this directory (but on any other case than the described use case above, please use a README
with an explanation):
ln -s .this.directory empty/.keep
To ignore files in this directory, you can add it in your root .gitignore
:
echo "/empty" >> .gitignore
To add the ignored file, use a parameter to force it:
git add -f empty/.keep
After the commit you have a broken symbolic link in your index and git creates the directory. The broken link has some advantages, since it is no regular file and points to no regular file. So it even fits to the part of the question "(that contains no files)", not by the intention but by the meaning, I guess:
find empty -type f
This commands shows an empty result, since no files are present in this directory. So most applications, which get all files in a directory usually do not see this link, at least if they do a "file exists" or a "is readable". Even some scripts will not find any files there:
$ php -r "var_export(glob('empty/.*'));"
array (
0 => 'empty/.',
1 => 'empty/..',
)
But I strongly recommend to use this solution only in special circumstances, a good written README
in an empty directory is usually a better solution. (And I do not know if this works with a windows filesystem...)