Как настроить историю после слияния двух не связанных репозиториев Mercurial? - PullRequest
5 голосов
/ 31 июля 2011

Я только что слил два хранилища, следуя совету, данному здесь . Поскольку оба хранилища совершенно не связаны, я использовал

hg convert --filemap fm rep1a rep1b
hg convert --filemap fm rep2a rep2b

для перемещения файлов в хранилище 1 в подкаталог a, а файлов из хранилища 2 в подкаталог b. В обоих хранилищах нет конфликтующих файлов, поэтому я объединил их оба.

Результатом является репозиторий, в котором есть ревизия слияния с двумя родителями, один из которых содержит историю репозитория 1, а другой - репозитория 2. Отлично!

mb--ma--2f--2e--2d--2c--2b--2a
      \
       -------------------------1e--1d--1c--1b--1a     

Теперь, что я действительно хочу, это история, где патчи сортируются по времени. Это не проблема, я использовал hg convert --datesort src dst, и все выглядит хорошо:

mb--ma--2f------2e--2d------2c--2b--2a
      \
       -----1e----------1d--------------1c--1b--1a     

Последнее, что мне сейчас нужно, это то, что все патчи объединяются, чтобы они имели линейный граф зависимостей, эффективно устраняя ревизию слияния `ma '. Я думаю, что решение состоит в том, чтобы перебазировать некоторые ревизии, но мне не хватает понимания, какая ревизия должна быть перебазирована на какую. Я экспериментировал с некоторыми, но ничего не получалось, как ожидалось. Одна попытка вызвала странные вопросы, такие как:

use (c)hanged version or (d)elete?

Как я могу сделать последний шаг?

РЕДАКТИРОВАТЬ: Я частично решил проблему. Так как rebase, казалось, все испортил (или я не до конца понял, в чем проблема), другой подход, кажется, работает намного лучше (как предложил Лассе): переписывание истории.

Я снова разбил репозиторий на две исходные части, используя hg convert с filemap, и вплоть до версии слияния. Затем я использовал трансплантацию ртути для пересадки одного хранилища в другое. Вуаля, линейная история!

2f--2e--2d--2c--2b--2a--1e--1d--1c--1b--1a

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

mb--2f--2e--2d--2c--2b--2a--1e--1d--1c--1b--1a

Теперь ревизии не отсортированы по времени, что было бы идеально, поэтому я попробовал hg convert --datesort repository.src repository.sorted, но результат все еще имеет наборы изменений в том же порядке, как показано выше. Я мог бы отсортировать их вручную, если у кого-то есть идея, как это можно сделать.

РЕДАКТИРОВАТЬ 2: Я наконец решил проблему, я создал новый репозиторий

mkdir repository_c
cd repository_c
hg init .

Я вытянул все патчи в правильном порядке, используя hg transplant:

hg transplant --source ../src 0:53
hg transplant --source ../src 70
hg transplant --source ../src 54:55
hg transplant --source ../src 71:79
hg transplant --source ../src 55:60
...

Это сработало, история линейная, а патчи отсортированы в правильном порядке. Так как не было конфликтующих исправлений, и версия заголовка идентична исходному хранилищу с двумя временными рамками, я счастлив. Я использовал расширение MQ для создания списка патч-файлов для всех ревизий и контролировал их вручную, но из того, что я могу сказать, история прекрасна.

1 Ответ

3 голосов
/ 03 октября 2011

Объединение несвязанных историй не работает должным образом, потому что каждый набор изменений является снимком проекта в каком-то состоянии. Если вы просто извлекаете -f или прививаете команду convert, вы получите репозиторий с явно несвязанной историей, собранной вместе. Вы не получите красивую историю, которая показывает историю привитого, добавляемую в основной проект за один раз, как вы этого хотите. Вместо этого вы получите кучу коммитов с файлами только из проекта A, а кучу только с файлами из проекта B. Короче говоря, это потому, что «в действительности так не происходило». Объединение графов истории не исправит содержимое этих наборов изменений.

Таким образом, единственный доступный ответ - это на самом деле воспроизводить историю проекта B внутри проекта A за один раз и в правой части пространства имен каталога A. Это можно сделать «вручную» с помощью hg export + import или с помощью некоторой комбинации hg convert --filemap и трансплантата или ребазера.

Я настроил вики-страницу, которую вы упомянули, чтобы осудить этот "совет" Вообще говоря, я вообще не рекомендую пытаться делать подобные вещи, опять же, потому что «на самом деле этого не произошло». Лучше просто извлечь всю историю проекта B за один коммит и иметь указатель на его истинную историю в сообщении о коммите.

...