Как объединить две истории git?
У меня есть два репозитория git, которые тангенциально связаны. А именно, содержание одного было предшественником другого. Я хотел бы каким-то образом добавить полную историю депозитария A к депозитарию B, чтобы подсказка A была родителем самого первого набора изменений репозитория B? Истории в обоих случаях довольно линейны.
это возможно?
1 ответов
вы можете попробовать использовать файл трансплантата (.git/info/grafts
), где вы можете перезаписать родительство фиксации (например, первое из projectB
наличие для родителя последнего из projectA
)
Смотрите также на "что .git / info / трансплантаты для?" и "как добавить прошлое в репозиторий git? " подробнее об этой манипуляции.
skalee комментарии о статье "Git: Прививка хранилища "(от SO user Бен Штрауб) для конкретного примера.
теперь то, что мы хотим сделать, это изменить первую фиксацию в "
nuevo
" repo ("New commit #1
"), так что его родитель является последним фиксатором в "старом" РЕПО ("Старый #3"). Время для вуду:
git fetch ../old master:ancient_history
Git позволяет вам получать из любого другого репозитория git, независимо от того, связано ли это РЕПО с ним или нет! Блестяще! Это оставляет нас с это:
обратите внимание, как мы переименовали старую главную ветвь в ancient_history. Если бы мы этого не сделали, ГИТ попытался бы объединить их и, вероятно, сдался бы с отвращением.
теперь у нас все еще есть проблема.
Два дерева не связаны, и на самом деле git pull даже не получит ветку ancient_history вообще. Нам нужен способ установить связь между ними.Git имеет объект под названием graft, который в основном подделывает родительскую связь между двумя коммитами.
Чтобы сделать один, просто вставьте строку в.git/info/grafts
файл в таком формате:
[ref] [parent]
оба они должны быть полным хэшем соответствующих коммитов. Итак, давайте найдем их:
$ git rev-list master | tail -n 1
d7737bffdad86dc05bbade271a9c16f8f912d3c6
$ git rev-parse ancient_history
463d0401a3f34bd381c456c6166e514564289ab2
$ echo d7737bffdad86dc05bbade271a9c16f8f912d3c6 \
463d0401a3f34bd381c456c6166e514564289ab2 \
> .git/info/grafts
(в одной строчке, а предложил by ssokolow)
echo $(git rev-list master | tail -n 1) $(git rev-parse ancient_history) > .git/info/grafts
там. Теперь наша история выглядит так это:
клонирование этого РЕПО приводит к следующему:
ой. Оказывается, трансплантаты действуют только для локального репозитория. Мы можем исправить это с помощью разумного применения
git fast-import
:
$ git fast-export --all > ../export
$ mkdir ../nuevo-complete
$ cd ../nuevo-complete
$ git init
$ git fast-import < ../export
git-fast-import statistics: [...]
(в одной строчке, а предложил by ssokolow)
git filter-branch $(git rev-parse ancient_history)..HEAD
это эффективно преобразует нашу" поддельную " ссылку истории в реальную.
Все инженеры должны будут повторно клонировать из этого нового репозитория, так как хэши будут отличаться, но это небольшая цена за отсутствие простоя и полную историю.
fast-import
кажется, просто импортирует информацию git, но ничего не проверяет из.git init
первоначально ставит вас на master, so вам понадобитсяgit reset --hard HEAD
чтобы на самом деле проверить файлы после васfast-import
.