How can I add an empty directory (that contains no files) to a Git repository?
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.
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
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
Here is a hack, but it's funny that it works (Git 2.2.1). Similar to what @Teka suggested, but easier to remember:
git submodule add path_to_repo
).submodules
. Commit a change..submodules
file and commit the change.Now, you have a directory that gets created when commit is checked out. An interesting thing though is that if you look at the content of tree object of this file you'll get:
fatal: Not a valid object name b64338b90b4209263b50244d18278c0999867193
I wouldn't encourage to use it though since it may stop working in the future versions of Git. Which may leave your repository corrupted.
If you want to add a folder that will house a lot of transient data in multiple semantic directories, then one approach is to add something like this to your root .gitignore...
/app/data/**/*.*
!/app/data/**/*.md
Then you can commit descriptive README.md files (or blank files, doesn't matter, as long as you can target them uniquely like with the *.md
in this case) in each directory to ensure that the directories all remain part of the repo but the files (with extensions) are kept ignored. LIMITATION: .
's are not allowed in the directory names!
You can fill up all of these directories with xml/images files or whatever and add more directories under /app/data/
over time as the storage needs for your app develop (with the README.md files serving to burn in a description of what each storage directory is for exactly).
There is no need to further alter your .gitignore
or decentralise by creating a new .gitignore
for each new directory. Probably not the smartest solution but is terse gitignore-wise and always works for me. Nice and simple! ;)
The Ruby on Rails log folder creation way:
mkdir log && touch log/.gitkeep && git add log/.gitkeep
Now the log directory will be included in the tree. It is super-useful when deploying, so you won't have to write a routine to make log directories.
The logfiles can be kept out by issuing,
echo log/dev.log >> .gitignore
but you probably knew that.