Конвертировать каждый git коммит в отдельную папку - PullRequest
3 голосов
/ 27 апреля 2020

У меня есть проект, который я выполнил в несколько отдельных этапов, каждый из которых строился отдельно.

Моя история коммитов выглядит следующим образом:

p1 -> p2 -> ... -> pn

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

project/
  p1/
  p2/
  ...
  pn/

Где каждый каталог p содержит все файлы и папки в ветви, когда он был зафиксирован (файлы, которые присутствовали в p1 и оставались неизменными до pn, должны быть включены с избыточностью в каждом каталоге). Как преобразовать каждый отдельный коммит в отдельную папку?

Ответы [ 2 ]

2 голосов
/ 27 апреля 2020

Используя скрипт, вы можете получить все хэши коммитов и для каждого коммита клонировать репозиторий и извлечение в нужный коммит:

#/bin/bash

commits=$(git log --pretty=format:"%h")
dest=/path/to/the/destination/folder
repo=git@github.com:username/repository.git

for commit in $commits; do
    echo $commit
    git clone -q $repo $dest/$commit
    cd $dest/$commit
    git checkout -q $commit
done

Запустите этот скрипт в вашей папке репозитория.

1 голос
/ 27 апреля 2020

Это довольно легко сделать, используя tar или zip для разархивирования архивов:

  1. Используйте git rev-list, чтобы сгенерировать список идентификаторов ha sh для каждого коммита.
  2. Используйте git archive, чтобы превратить каждый моментальный снимок фиксации в архив.
  3. Используйте tar или unzip, чтобы превратить каждый архив в дерево исходных кодов в пронумерованной папке p/.

В сценарии оболочки (bash, более или менее) это:

step=1
git rev-list --reverse --topo-order $last |
while read rev; do
    mkdir /path/to/p$step
    git archive $rev | tar -C /path/to/p$step -xf -
    : $((step+=1))
done

(примечание: приведенное выше не проверено).

Изменить, чтобы упомянуть забытую часть : установите last выше для последнего коммита, который вы хотите экспортировать. Используйте необработанный идентификатор ha sh, если хотите, или название ветви, если хотите. Имя ветви Git просто называет последний коммит в ветви (всегда по определению). L oop автоматически нумерует извлеченные папки последовательно в соответствии с результатом списка оборотов, поэтому если при запуске с последнего коммита и при работе в обратном направлении насчитывается 5000 коммитов, вы получите 5000 папок, пронумерованных начиная с 1 (по запросу) .

Обратите внимание, что каждый коммит - это требуемый снимок - коммиты не содержат изменений, они содержат моментальные снимки - но коммит в репозитории Git хранит свои файлы в специальном, Только для чтения, Git -только формат архива, сжатый таким образом, что идентичные файлы сразу же дублируются, а подобные файлы в конечном итоге (хотя и не сразу) занимают очень мало места. Вы хотели каждый снимок как обычные файлы. Это означает, что вы должны получить от Git до extract их.

Команда git checkout делает именно это: она извлекает файлы . Но он делает слишком много: он делает это в одном рабочем дереве вместе с ведением информации, так что git commit или другой git checkout могут быть сделаны позже. Если вы сделаете еще один git checkout, Git удалит и заменит все эти файлы на файлы из следующего , зафиксированного вами. Так что git checkout - это не та команда, которую мы расширяем для снимка в нормальные файлы.

(на самом деле это не git archive, но как только мы превратим снимок в стандартный архив tar или zip, мы можем использовать стандартный инструмент tar или unzip для извлечения файлов где-то, что является , а не рабочим деревом, где эти файлы защищены от случайного забивания другим git checkout.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...