Ответ 1
Вы можете попробовать использовать файл трансплантата (.git/info/grafts
), где вы могли бы перезаписать родительскую запись коммита (например, первый из projectB
, имеющий для родителя последний из projectA
)
См. также "Что такое .git/info/grafts для?" и "Как добавить прошлое к git репозиторий?" для получения дополнительной информации об этой манипуляции.
skalee комментарии о статье " Git: Grafting repositories" (от пользователя SO Ben Straub) для конкретного примера.
Теперь то, что мы хотим сделать, это изменить первое коммит в "
nuevo
" repo ( "New commit #1
" ), чтобы его родительский элемент был последним фиксатором в "старом" репо ( "Старый №3" ), Время для некоторых вуду:
git fetch ../old master:ancient_history
Git позволяет вам получать из любого другого репозитория git, связано ли это с репо с ним или нет! Brilliant! Это оставляет нам это:
Обратите внимание, как мы переименовали старую ветвь мастера в old_history. Если бы мы не имели, git попытались бы объединить эти два и, вероятно, отказались от отвращения.
Теперь у нас все еще есть проблема.
Два дерева arent соединены, и на самом деле притяжение git вообще не получит ветку древней истории. Нам нужен способ установить связь между ними.Git имеет объект, называемый трансплантатом, который в основном подделывает родительскую связь между двумя коммитами.
Чтобы сделать это, просто вставьте строку в файл.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
(в одной строке, как предлагаемый, ssokolow)
echo $(git rev-list master | tail -n 1) $(git rev-parse ancient_history) > .git/info/grafts
Там. Теперь наша история выглядит так:
Клонирование этого репо приводит к следующему:
Woops. Оказывается, трансплантаты вступают в силу только для локального репозитория. Мы можем исправить это с помощью разумного применения
git fast-import
:
$ git fast-export --all > ../export
$ mkdir ../nuevo-complete
$ cd ../nuevo-complete
$ git init
$ git fast-import < ../export
git-fast-import statistics: [...]
(в одной строке, как предлагаемый ssokolow)
git filter-branch $(git rev-parse ancient_history)..HEAD
Это эффективно преобразует нашу "фальшивую" историю в реальную. Все инженеры должны будут повторно клонировать из этого нового репозитория, так как хеши будут разными, но это небольшая цена, чтобы заплатить за простой и полную историю.
fast-import
просто импортирует информацию git, но ничего не проверяет.git init
изначально ставит вас на хозяина, поэтому вам нужноgit reset --hard HEAD
, чтобы проверить файлы послеfast-import
.