Есть ли "git export" (например, "svn export")? - PullRequest
2263 голосов
/ 02 октября 2008

Мне было интересно, есть ли хорошее решение "git export", которое создает копию дерева без каталога репозитория .git. Есть как минимум три метода, о которых я знаю:

  1. git clone с последующим удалением каталога репозитория .git.
  2. git checkout-index ссылается на эту функцию, но начинается с «Просто прочитайте нужное дерево в индекс ...», что я не совсем уверен, как это сделать.
  3. git-export - это сторонний скрипт, который, по сути, git clone отправляет во временное местоположение, за которым следует rsync --exclude='.git' в конечный пункт назначения.

Ни одно из этих решений не кажется мне удовлетворительным. Наиболее близким к svn export может быть вариант 1, потому что оба требуют, чтобы целевой каталог был пустым в первую очередь. Но вариант 2 кажется еще лучше, если предположить, что я могу понять, что значит читать дерево в индексе.

Ответы [ 31 ]

2300 голосов
/ 02 октября 2008

Вероятно, самый простой способ достичь этого - git archive. Если вам действительно нужно только расширенное дерево, вы можете сделать что-то вроде этого.

git archive master | tar -x -C /somewhere/else

В большинстве случаев мне нужно «экспортировать» что-то из git, в любом случае мне нужен сжатый архив, поэтому я делаю что-то вроде этого.

git archive master | bzip2 >source-tree.tar.bz2

ZIP архив:

git archive --format zip --output /full/path/to/zipfile.zip master 

git help archive для более подробной информации, он довольно гибкий.


Имейте в виду, что, хотя архив не будет содержать каталог .git, он, однако, будет содержать другие скрытые специфичные для git файлы, такие как .gitignore, .gitattributes и т. Д. Если вы не хотите, чтобы они были в архиве, убедитесь, что вы используете атрибут export-ignore в файле .gitattributes и подтвердите это перед созданием вашего архива. Подробнее ...


Примечание. Если вы заинтересованы в экспорте индекса, введите команду

git checkout-index -a -f --prefix=/destination/path/

(см. ответ Грега для более подробной информации)

313 голосов
/ 02 октября 2008

Я выяснил, что означает вариант 2. Из репозитория вы можете сделать:

git checkout-index -a -f --prefix=/destination/path/

Косая черта в конце пути важна, иначе это приведет к тому, что файлы будут в / destination с префиксом 'path'.

Поскольку в нормальной ситуации индекс содержит содержимое репозитория, ничего особенного для «чтения нужного дерева в индекс» делать нечего. Это уже там.

Флаг -a необходим для проверки всех файлов в индексе (я не уверен, что означает опускать этот флаг в этой ситуации, поскольку он не выполняет то, что я хочу). Флаг -f принудительно перезаписывает любые существующие файлы в выводе, чего обычно не делает эта команда.

Похоже, это был тот "экспорт git", который я искал.

248 голосов
/ 09 декабря 2008

git archive также работает с удаленным репозиторием.

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master | tar -xf -

Чтобы экспортировать конкретный путь в репо, добавьте столько путей, сколько вы пожелаете, в качестве последнего аргумента для git, например ::

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master path1/ path2/ | tar -xv
53 голосов
/ 30 октября 2013

enter image description here

Ответ в особом случае, если хранилище размещено на GitHub.

Просто используйте svn export.

Насколько я знаю, Github не позволяет archive --remote. Хотя GitHub svn-совместим , и у них есть все доступные git-репозитории svn, так что вы можете просто использовать svn export, как обычно, с некоторыми изменениями в вашем URL GitHub.

Например, чтобы экспортировать весь репозиторий, обратите внимание на то, как trunk в URL заменяет master (или независимо от того, установлена ​​ли ветвь HEAD для проекта на ):

svn export https://github.com/username/repo-name/trunk/

И вы можете экспортировать один файл или даже определенный путь или папку:

svn export https://github.com/username/repo-name/trunk/src/lib/folder

Пример с jQuery JavaScript Library

Ветвь HEAD или ветвь master будут доступны с использованием trunk:

svn ls https://github.com/jquery/jquery/trunk

Не HEAD ветви будут доступны под /branches/:

svn ls https://github.com/jquery/jquery/branches/2.1-stable

Все теги под /tags/ таким же образом:

svn ls https://github.com/jquery/jquery/tags/2.1.3
39 голосов
/ 02 октября 2008

Из Git Manual :

Использование git-checkout-index для "экспорта всего дерева"

Возможность префикса в основном упрощает использование git-checkout-index в качестве функции «экспортировать как дерево». Просто прочитайте нужное дерево в указатель и выполните:

$ git checkout-index --prefix=git-export-dir/ -a

38 голосов
/ 16 октября 2008

Я написал простую оболочку вокруг git-checkout-index, которую вы можете использовать следующим образом:

git export ~/the/destination/dir

Если каталог назначения уже существует, вам нужно добавить -f или --force.

Установка проста; просто поместите скрипт в ваш PATH и убедитесь, что он исполняемый.

Github-репозиторий для git-export

36 голосов
/ 12 мая 2009

Похоже, что это меньше проблема с Git, чем SVN. Git помещает только папку .git в корень репозитория, тогда как SVN помещает папку .svn в каждый подкаталог. Таким образом, "svn export" избегает рекурсивной магии командной строки, тогда как в Git рекурсия не нужна.

26 голосов
/ 23 февраля 2012

Эквивалент

svn export . otherpath

внутри существующего репо -

git archive branchname | (cd otherpath; tar x)

Эквивалент

svn export url otherpath

есть

git archive --remote=url branchname | (cd otherpath; tar x)
22 голосов
/ 28 марта 2014

Если вы не исключаете файлы с .gitattributes export-ignore, попробуйте git checkout

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout -f -q

-f
При проверке путей из индекса, не сбой при unmerged записи; вместо этого необработанные записи игнорируются.

и

-q
Избегайте многословия

Кроме того, вы можете получить любую ветвь или тэг или из конкретной ревизии, например, в SVN, просто добавив SHA1 (SHA1 в Git эквивалентен номеру ревизии в SVN)

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout 2ef2e1f2de5f3d4f5e87df7d8 -f -q -- ./

/path/to/checkout/ должно быть пустым, Git не будет удалять файлы, но будет перезаписывать файлы с одинаковыми именами без предупреждения

UPDATE: Чтобы избежать обезглавленной проблемы или оставить нетронутым рабочий репозиторий при использовании извлечения для экспорта с тегами, ветвями или SHA1, необходимо добавить -- ./ в конце

Двойная черта -- сообщает git, что все после черточек являются путями или файлами, а также в этом случае git checkout не меняет HEAD

Примеры:

Эта команда получит только каталог libs, а также файл readme.txt из этого коммита

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout fef2e1f2de5f3d4f5e87df7d8 -f -q -- ./libs ./docs/readme.txt

Это создаст (перезаписать) my_file_2_behind_HEAD.txt два коммита за головой HEAD^2

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout HEAD^2 -f -q -- ./my_file_2_behind_HEAD.txt

Чтобы получить экспорт из другой ветки

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout myotherbranch -f -q -- ./

Обратите внимание, что ./ относительно корня хранилища

21 голосов
/ 13 сентября 2011

Я широко использую git-подмодули. Этот работает для меня:

rsync -a ./FROM/ ./TO --exclude='.*'
...