Как предварительно ожидать прошлое в репозиторий мерзавца?

Я получил некоторый исходный код и решил использовать мерзавца для него начиная с моего коллеги, используемого mkdir $VERSION и т.д. подход. В то время как прошлое кода в настоящее время кажется неважным, я все еще хотел бы подвергнуть его управлению мерзавца также для лучше понимания процесса разработки. Так:

Что удобный способ состоит в том, чтобы поместить те прошлые версии в моего уже существующего мерзавца repo? В настоящее время нет никакого удаленного repo, таким образом, я не возражаю переписывать историю, но решение, которое принимает удаленные репозитории во внимание, будет, конечно, предпочтено, если это не будет намного больше coplicated затем. Бонусные очки для сценария, для которого больше не нужно взаимодействие или на основе каталога или на основе основанной на архивном файле истории.

25
задан Tobias Kienzler 26 April 2014 в 23:16
поделиться

3 ответа

Для импорта старых снимков вы найдете полезными некоторые инструменты в каталоге contrib / fast-import Git. Или, если у вас уже есть каждый старый снимок в каталоге, вы можете сделать что-то вроде этого:

# Assumes the v* glob will sort in the right order
# (i.e. zero padded, fixed width numeric fields)
# For v1, v2, v10, v11, ... you might try:
#     v{1..23}     (1 through 23)
#     v?{,?}       (v+one character, then v+two characters)
#     v?{,?{,?}}   (v+{one,two,three} characters)
#     $(ls -v v*)  (GNU ls has "version sorting")
# Or, just list them directly: ``for d in foo bar baz quux; do''
(git init import)
for d in v*; do
    if mv import/.git "$d/"; then
        (cd "$d" && git add --all && git commit -m"pre-Git snapshot $d")
        mv "$d/.git" import/
    fi
done
(cd import && git checkout HEAD -- .)

Затем загрузите старую историю в свой рабочий репозиторий:

cd work && git fetch ../import master:old-history

После того, как вы сохраните старую историю и историю на основе Git в В том же репозитории у вас есть несколько вариантов операции добавления: трансплантаты и замены.

Графты - это механизм для каждого репозитория, позволяющий (возможно, временно) редактировать происхождение различных существующих коммитов. Графты контролируются файлом $ GIT_DIR / info / grafts (описанным в разделе «info / grafts» справочной страницы gitrepository-layout ).

INITIAL_SHA1=$(git rev-list --reverse master | head -1)
TIP_OF_OLD_HISTORY_SHA1=$(git rev-parse old-history)
echo $INITIAL_SHA1 $TIP_OF_OLD_HISTORY_SHA1 >> .git/info/grafts

Установив трансплантат (исходная первоначальная фиксация не имела родителей, трансплантат дал ему одного родителя), вы можете использовать все обычные инструменты Git для поиска и просмотра расширенной истории (например, git log теперь должен показывать старую историю после ваших коммитов).

Основная проблема графтов заключается в том, что они ограничены вашим хранилищем.Но если вы решите, что они должны быть постоянной частью истории, вы можете использовать git filter-branch , чтобы сделать их такими (сделайте резервную копию tar / zip своего .git ) сначала dir; git filter-branch сохранит исходные ссылки, но иногда проще использовать обычную резервную копию).

git filter-branch --tag-name-filter cat -- --all
rm .git/info/grafts

Механизм замены более новый (Git 1.6.5 +), но его можно отключить для каждой команды ( git --no-replace-objects… ) и они могут подтолкнуть к более легкому обмену. Замена работает с отдельными объектами (капли, деревья, коммиты или аннотированные теги), поэтому этот механизм также является более общим. Механизм замены описан на странице руководства git replace . Из-за общности «предварительная» настройка требует больше усилий (мы должны создать новую фиксацию вместо того, чтобы просто назвать нового родителя):

# the last commit of old history branch
oldhead=$(git rev-parse --verify old-history)
# the initial commit of current branch
newinit=$(git rev-list master | tail -n 1)
# create a fake commit based on $newinit, but with a parent
# (note: at this point, $oldhead must be a full commit ID)
newfake=$(git cat-file commit "$newinit" \
        | sed "/^tree [0-9a-f]\+\$/aparent $oldhead" \
        | git hash-object -t commit -w --stdin)
# replace the initial commit with the fake one
git replace -f "$newinit" "$newfake"

Совместное использование этой замены не является автоматическим. Вы должны нажать часть (или все) refs / replace , чтобы поделиться заменой.

git push some-remote 'refs/replace/*'

Если вы решили сделать замену постоянной, используйте git filter-branch (так же, как с grafts; сначала сделайте резервную копию tar / zip каталога .git ):

git filter-branch --tag-name-filter cat -- --all
git replace -d $INITIAL_SHA1
25
ответ дан 28 November 2019 в 21:40
поделиться

Самым простым подходом, конечно же, является создание нового репозитория git, сначала фиксируя историю в начале, а затем повторно применяя исправления старого репо. Но я бы предпочел решение, которое требует меньше времени за счет автоматизации.

2
ответ дан 28 November 2019 в 21:40
поделиться

Если вы не хотите изменять коммиты в своем репозитории, вы можете использовать графты, чтобы переопределить родительскую информацию для коммита. Это то, что делает репозиторий ядра Linux, чтобы получить историю до того, как они начали использовать Git.

Это сообщение: http://marc.info/?l=git&m=119636089519572 , похоже, содержит лучшую документацию, которую я могу найти.

Вы должны создать последовательность коммитов, относящуюся к вашей истории pre-git, а затем использовать файл .git / info / grafts , чтобы Git использовал последний коммит в этой последовательности как родительский для первый коммит, созданный с помощью Git.

3
ответ дан 28 November 2019 в 21:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: