Экспортируйте все коммиты в ZIP-файлы или каталоги

Как можно экспортировать все коммиты в ZIP-файлы (содержащие все файлы, а не только patch/diff):

myproject-commit1-67d91ab.zip
myproject-commit2-9283acd.zip
myproject-commit3-c57daa6.zip
...

или в каталогах:

myproject-commit1-67d91ab/
myproject-commit2-9283acd/
myproject-commit3-c57daa6/

?

Я думал о таких командах, как:

git archive --format zip --output myproject-commit3.zip c57daa6

Как экспортировать конкретный коммит с помощью git-архива? а как получить все коммиты?

Заметки:

  • цель состоит в том, чтобы сделать экспорт всех файлов каждого коммита, чтобы я мог получить к ним доступ, даже если у меня нет git на машине

  • ответ из Как я могу экспортировать наборы изменений Git из одного хранилища в другое через sneaker net (внешние файлы)? создает .bundle файл, но, кажется, невозможно получить к нему доступ без gitтак что это не то, что я ищу

  • это почти работает:

    for ((i = 0;; ++i)); do git checkout master~$i || break; tar czf ../myproject-commit$i.tgz .; done
    

    но он также архивирует все файлы в текущем каталоге, которые не являютсяgit addедь в репо... Как избежать этой проблемы?

3 ответа

Решение

Вы не можете, кроме тех методов, о которых вы уже думаете.

В частности, чтобы превратить каждый коммит в zip-архив (один отдельный архив на коммит), просто переберите каждый коммит, превратив каждый коммит в zip-архив.

Ваш метод итерации просто должен пройти все возможные коммиты, а не только всех прародителей master ветвь, и вы должны использовать git archive на каждом таком коммите. Следовательно:

git rev-list --all |
    while read hash; do git archive ...options... $hash
done

Команда git rev-list --all говорит Git распечатать все доступные хеш-идентификаторы коммитов в некотором порядке. Чтобы изменить порядок, используйте различные параметры сортировки, доступные для обоих git rev-list а также git log (например, --author-date-order или же --topo-order).

Если вам не нужен каждый коммит - если вы хотите вместо него только прародителей мастера - вы все равно можете сделать это с git rev-list:

git rev-list --first-parent master | ...

Здесь, так как Git ходит только прародители, начиная с того, что совершить master идентифицирует, хеш-идентификаторы будут выводиться в том, что Git считает прямым порядком, то есть в обратном направлении через прародителей филиала:

...--o--o--o--o--o--o------o   <-- master
      \        \          /
       \        X--X--...X   <-- somebranch
        \         /
         X--X----X--X   <-- anotherbranch

Ни один из X коммиты появятся, так как они не находятся на линии первого родителя. (Без --first-parent, так как все коммиты на somebranchи все кроме последнего на anotherbranch, также на masterВы бы получили все X совершает.)

[Basj добавляет следующее, что, похоже, связано с bash из-за $((i=i+1)):] Редактировать: это готовая команда для выполнения, как описано в вопросе:

git rev-list --all --reverse | while read hash; do git archive --format zip --output ../myproject-commit$((i=i+1))-$hash.zip $hash; done

[torek чувствует необходимость добавить:-): Обратите внимание, что вышеприведенное перечисляет коммиты последовательно, даже если это не обратимое отображение.]

Я немного улучшил решение от @torek.
Этот экспорт коммитов, которые "обычно видны" при использовании git log (все коммиты экспортируются в папку zip):

      mkdir zip && git log --format=%h --reverse |
    while read hash;
    do git archive --format zip --output zip/$((i=i+1))-project-$hash.zip $hash;
done

Если вы хотите также дату и время (без «проекта»), используйте это:

      mkdir zip && git log --format="%h %ad" --date=format:"%d.%m.%Y-%H.%M" --reverse |
    while read hash date;
    do git archive --format zip --output zip/$((i=i+1))-$hash-$date.zip $hash;
done

Если вы хотите экспортировать все коммиты в папки (вместо zip-архивов), используйте это:

      mkdir zip && git log --format="%h %ad" --date=format:"%d.%m.%Y-%H.%M" --reverse |
    while read hash date;
    do git archive --format zip --output zip/$((i=i+1))-$hash-$date.zip $hash;
done && find zip -name '*.zip' -exec sh -c 'unzip "$1" -d "${1%.*}"' _ {} \; && rm zip/*.zip

Вы можете скачать свой проект с определенным коммитом в zip-файле, используя

https://host_url/{user_name}/{project_name}/archive/{commit_id}.zip

РЕДАКТИРОВАТЬ

Вы можете сделать это с помощью командной строки.

git archive -o commit_id.tar --remote=<repo_url> <commit_id>
Другие вопросы по тегам