What's the best way to extract a tree from a git repository?

Extracting a blob (file) from an arbitrary revision is easy with git show, e.g.:

 git show master:src/hello-world.c > /tmp/hello.c

However, I’d like to know if is there a similar way in git to extract a tree (directory) and everything under it recursively?

  • How to rebase in IntelliJ IDEA
  • Prevent a branch from pushing to a specific remote
  • How to change the text editor in git to Sublime - currently git commit commands are opening in Notepad
  • git init in a git subdirectory
  • Git - how do I view the change history of a method/function?
  • How do I generate the GitHub OAuth token for organization accounts?
  • I’ve written a small script that does this, so I’ll add that as a possible answer. It seems that this is the kind of thing that may well be built in to git, but I just don’t know how to find it…

  • Gitignore the current modifications but keep the old versions in the repo
  • Git: Never Commit Changed Files (But still keep original revisioned.)
  • SourceTree custom action doesn't work but works through Git terminal window
  • Has anybody seen git create a commit that has no date & an all-zero hash?
  • Using Git in Visual Studio, how do I navigate repository files?
  • Paramiko channel is never recv_ready
  • 3 Solutions collect form web for “What's the best way to extract a tree from a git repository?”

    You can use git archive for this.

    git archive master:src/ | tar -C destination -x
    

    You can use read-tree and checkout-index with a temporary index file:

    GIT_INDEX_FILE=.tmp.index { git read-tree master:src &&
                                git checkout-index -a --prefix=dest/; 
                                rm -f .tmp.index; }
    

    (Line breaks added for clarity, but it’s really a one-liner.)

    For a bare repository you have to pretend that a working tree exists and that you are in it:

    GIT_INDEX_FILE=.tmp.index GIT_DIR=/path/to/repo.git GIT_WORK_TREE=. {
        git read-tree master:src &&
        git checkout-index -a --prefix=/path/to/dest/; 
        rm -f .tmp.index; }
    

    If run from inside the bare repository you can omit setting GIT_DIR.

    I’m doing this at the moment with this script:

    http://gist.github.com/498447

    … which parses the output of git ls-tree -r -z <tree-ish>. You can pass it anything that git ls-tree can understand as a tree, e.g:

    extract-tree-from-git.py master:src/tests/ /tmp/extracted-tests/
    extract-tree-from-git.py HEAD^ /tmp/parent-of-head/
    
    Git Baby is a git and github fan, let's start git clone.