Какой лучший способ извлечь дерево из репозитория git?

Извлечение blob (файла) из произвольной версии легко с помощью git show, например:

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

Однако, я хотел бы знать, есть ли аналогичный способ в git для извлечения дерева (каталога) и всего под ним рекурсивно?

Я написал небольшой script, который делает это, поэтому я добавлю это как возможный ответ. Похоже, что это та вещь, которая вполне может быть встроена в git, но я просто не знаю, как ее найти...

Ответ 1

Вы можете использовать git archive для этого.

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

Ответ 2

Вы можете использовать read-tree и checkout-index с временным индексным файлом:

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_DIR.

Ответ 3

Я делаю это в данный момент с помощью этого script:

http://gist.github.com/498447

... который анализирует вывод git ls-tree -r -z <tree-ish>. Вы можете передать ему все, что git ls-tree может понимать как дерево, например:

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