How can I add an empty directory to a Git reposito

2018-12-31 00:48发布

How can I add an empty directory (that contains no files) to a Git repository?

28条回答
不流泪的眼
2楼-- · 2018-12-31 01:05

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!

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

    $ mkdir path/to/empty-folder
    
  3. Add it to the index using a plumbing command and the empty tree SHA-1:

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

    Type the command and then enter the second line. Press Enter and then Ctrl + D to terminate your input. Note: the format is mode [SPACE] type [SPACE] SHA-1hash [TAB] path (the tab is important, the answer formatting does not preserve it).

  4. That's it! Your empty folder is in your index. All you have to do is commit.

This solution is short and apparently works fine (see the EDIT!), but it is not that easy to remember...

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

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.

查看更多
流年柔荑漫光年
3楼-- · 2018-12-31 01:06

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.

查看更多
零度萤火
4楼-- · 2018-12-31 01:06

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
查看更多
像晚风撩人
5楼-- · 2018-12-31 01:08

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.

查看更多
旧时光的记忆
6楼-- · 2018-12-31 01:08

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! ;)

enter image description here

查看更多
ら面具成の殇う
7楼-- · 2018-12-31 01:08

Sometimes I have repositories with folders that will only ever contain files considered to be "content"—that is, they are not files that I care about being versioned, and therefore should never be committed. With Git's .gitignore file, you can ignore entire directories. But there are times when having the folder in the repo would be beneficial. Here's a excellent solution for accomplishing this need.

What I've done in the past is put a .gitignore file at the root of my repo, and then exclude the folder, like so:

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

However, these folders then don't become part of the repo. You could add something like a README file in there. But then you have to tell your application not to worry about processing any README files.

If your app depends on the folders being there (though empty), you can simply add a .gitignore file to the folder in question, and use it to accomplish two goals:

Tell Git there's a file in the folder, which makes Git add it to the repo. Tell Git to ignore the contents of this folder, minus this file itself. Here is the .gitignore file to put inside your empty directories:

*
!.gitignore

The first line (*) tells Git to ignore everything in this directory. The second line tells Git not to ignore the .gitignore file. You can stuff this file into every empty folder you want added to the repository.

查看更多
登录 后发表回答