How can I add an empty directory to a Git repository?

后端 未结 30 2458
离开以前
离开以前 2020-11-21 04:52

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

相关标签:
30条回答
  • 2020-11-21 05:01

    Another way to make a directory stay (almost) empty (in the repository) is to create a .gitignore file inside that directory that contains these 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.

    This also gives the benefit that files in that directory won't show up as "untracked" when you do a git status.

    Making @GreenAsJade's comment persistent:

    I think it's worth noting that this solution does precisely what the question asked for, but is not perhaps what many people looking at this question will have been looking for. This solution guarantees that the directory remains empty. It says "I truly never want files checked in here". As opposed to "I don't have any files to check in here, yet, but I need the directory here, files may be coming later".

    0 讨论(0)
  • 2020-11-21 05:02

    Reading @ofavre's and @stanislav-bashkyrtsev's answers using broken GIT submodule references to create the GIT directories, I'm surprised that nobody has suggested yet this simple amendment of the idea to make the whole thing sane and safe:

    Rather than hacking a fake submodule into GIT, just add an empty real one.

    Enter: https://gitlab.com/empty-repo/empty.git

    A GIT repository with exactly one commit:

    commit e84d7b81f0033399e325b8037ed2b801a5c994e0
    Author: Nobody <none>
    Date: Thu Jan 1 00:00:00 1970 +0000
    

    No message, no committed files.

    Usage

    To add an empty directory to you GIT repo:

    git submodule add https://gitlab.com/empty-repo/empty.git path/to/dir
    

    To convert all existing empty directories to submodules:

    find . -type d -empty -delete -exec git submodule add -f https://gitlab.com/empty-repo/empty.git \{\} \;
    

    Git will store the latest commit hash when creating the submodule reference, so you don't have to worry about me (or GitLab) using this to inject malicious files. Unfortunately I have not found any way to force which commit ID is used during checkout, so you'll have to manually check that the reference commit ID is e84d7b81f0033399e325b8037ed2b801a5c994e0 using git submodule status after adding the repo.

    Still not a native solution, but the best we probably can have without somebody getting their hands really, really dirty in the GIT codebase.

    Appendix: Recreating this commit

    You should be able to recreate this exact commit using (in an empty directory):

    # Initialize new GIT repository
    git init
    
    # Set author data (don't set it as part of the `git commit` command or your default data will be stored as “commit author”)
    git config --local user.name "Nobody"
    git config --local user.email "none"
    
    # Set both the commit and the author date to the start of the Unix epoch (this cannot be done using `git commit` directly)
    export GIT_AUTHOR_DATE="Thu Jan 1 00:00:00 1970 +0000"
    export GIT_COMMITTER_DATE="Thu Jan 1 00:00:00 1970 +0000"
    
    # Add root commit
    git commit --allow-empty --allow-empty-message --no-edit
    

    Creating reproducible GIT commits is surprisingly hard…

    0 讨论(0)
  • 2020-11-21 05:03

    I always build a function to check for my desired folder structure and build it for me within the project. This gets 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 讨论(0)
  • 2020-11-21 05:05

    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 讨论(0)
  • 2020-11-21 05:05

    You can't and unfortunately will never be able to. This is a decision made by Linus Torvald himself. He knows what's good for us.

    There is a rant out there somewhere I read once.

    I found Re: Empty directories.., but maybe there is another one.

    You have to live with the workarounds...unfortunately.

    0 讨论(0)
  • 2020-11-21 05:06

    Git does not track empty directories. See the Git FAQ for more explanation. The suggested workaround is to put a .gitignore file in the empty directory. I do not like that solution, because the .gitignore is "hidden" by Unix convention. Also there is no explanation why the directories are empty.

    I suggest to put a README file in the empty directory explaining why the directory is empty and why it needs to be tracked in Git. With the README file in place, as far as Git is concerned, the directory is no longer empty.

    The real question is why do you need the empty directory in git? Usually you have some sort of build script that can create the empty directory before compiling/running. If not then make one. That is a far better solution than putting empty directories in git.

    So you have some reason why you need an empty directory in git. Put that reason in the README file. That way other developers (and future you) know why the empty directory needs to be there. You will also know that you can remove the empty directory when the problem requiring the empty directory has been solved.


    To list every empty directory use the following command:

    find -name .git -prune -o -type d -empty -print
    

    To create placeholder READMEs in every empty directory:

    find -name .git -prune -o -type d -empty -exec sh -c \
      "echo this directory needs to be empty because reasons > {}/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
    

    To list every README after they are already created:

    find -name README.emptydir
    
    0 讨论(0)
提交回复
热议问题