Как объединить две истории 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, независимо от того, связано ли это РЕПО с ним или нет! Блестяще! Это оставляет нас с это:

enter image description here

обратите внимание, как мы переименовали старую главную ветвь в 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 

там. Теперь наша история выглядит так это:

enter image description here

клонирование этого РЕПО приводит к следующему:

enter image description here

ой. Оказывается, трансплантаты действуют только для локального репозитория. Мы можем исправить это с помощью разумного применения 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 

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

enter image description here

As Qix комментарии ниже:

fast-import кажется, просто импортирует информацию git, но ничего не проверяет из.
git init первоначально ставит вас на master, so вам понадобится git reset --hard HEAD чтобы на самом деле проверить файлы после вас fast-import.