什么';从git存储库中提取树的最佳方法是什么?

什么';从git存储库中提取树的最佳方法是什么?,git,Git,使用git show,可以轻松地从任意版本中提取blob(文件),例如: git show master:src/hello-world.c > /tmp/hello.c 但是,我想知道在git中是否有类似的方法递归地提取树(目录)及其下的所有内容 我已经写了一个小脚本来实现这一点,所以我将添加它作为一个可能的答案。这似乎是git内置的东西,但我不知道如何找到它…您可以使用git archive来实现这一点 git archive master:src/ | tar -C destin

使用
git show
,可以轻松地从任意版本中提取blob(文件),例如:

 git show master:src/hello-world.c > /tmp/hello.c
但是,我想知道在git中是否有类似的方法递归地提取树(目录)及其下的所有内容


我已经写了一个小脚本来实现这一点,所以我将添加它作为一个可能的答案。这似乎是git内置的东西,但我不知道如何找到它…

您可以使用git archive来实现这一点

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

我现在正在用这个脚本做这件事:

。。。它解析git ls tree-r-z的输出。您可以将
git ls tree
可以理解为树的任何内容传递给它,例如:

extract-tree-from-git.py master:src/tests/ /tmp/extracted-tests/
extract-tree-from-git.py HEAD^ /tmp/parent-of-head/

您可以将
读取树
签出索引
与临时索引文件一起使用:

GIT_INDEX_FILE=.tmp.index { git read-tree master:src &&
                            git checkout-index -a --prefix=dest/; 
                            rm -f .tmp.index; }
(为清晰起见,增加了换行符,但实际上是一行。)

对于裸存储库,您必须假设存在一个工作树,并且您在其中:

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; }

如果从裸存储库中运行,您可以省略设置
GIT\u DIR

,这是一个即时的答案!谢谢,这很理想-比我的脚本快得多。另外一个额外的好处是,你可以远程完成它,而另一个(甚至是裸的)存储库使用--RemoteSmart:)除了不依赖tar之外,还有什么特别的原因让你更喜欢这个答案而不是你的
git归档文件的答案吗?@Mark Longair:这个更“低级”;归档解决方案更像是一个用户命令。我不知道这台是更好还是更差。我把答案分开,因为我真的很想知道哪一个更受欢迎。正如cxreg所提到的,对于裸存储库和git 1.7.0.4,“git签出索引”步骤失败,因为“致命:此操作必须在工作树中运行”。(在设置了GIT_INDEX_文件并使用了--prefix的情况下,这似乎有点奇怪。)所以我接受另一个答案,因为裸存储库的情况对我来说很重要,但了解这一点非常有用-谢谢两者。@DavidSchmitt:我不理解你的编辑。也许我不理解这个用例,签出到一个空存储库的子目录似乎有点奇怪。为什么我们需要
$(pwd)
,为什么我们需要
-f
传递到
签出索引
?我想你已经完全改变了我回答的意图,但我不是很确定。@Charles:对不起,编码晚了。其目的是GIT_WORK_树和GIT_INDEX_文件必须是绝对路径,否则您会得到评论的错误标记。我现在将其更改为虚拟值。希望这不那么晦涩。实际上,它现在应该能够独立于cwd运行,并将src/目录从$GIT_DIR中的master签出到$GIT_WORK_树中。