Воспитание в Mercurial: как собрать вместе два независимых svn-клона?

Вот ситуация: разработчик Foo создал репозиторий hg из нашего репозитория svn. Репозиторий Hoo Foo был всего лишь мелким клоном ствола в svn (без svn-веток, тегов и т. Д., А история была неполной [около 100 наборов изменений]). Developer Bar сделал то же самое, но клонировал весь репозиторий SVN, включая всю историю, ветки, теги и т. Д. И Foo, и Bar выполнили разветвленную разработку для своих репозиториев.

У обоих репозиториев есть общий предок SVN, но у каждого репозитория hg свой номер версии. Я хотел бы переписать изменения Фу с общего предка на репо Бар. Вот схема того, что я ищу:

Репо Фу:

C'-D'-E-F---G
       \   /
        H-I

Репо бара:

...A-B-C-D-J-K---L
            \   /
             M-N

C, C 'и D,D' имеют одинаковое содержание, но разные номера версий и комментарии.

Цель:

...A-B-C-D--E-F---G
          \  \   /
           \  H-I
            \
             J-K---L
              \   /
               M-N

У меня закончились идеи о том, как это сделать. Я попытался преобразовать --splicemap splice.map [файл splice.map, содержащий E D] (ничего не сделал). Клону -f удалось собрать все в одном репо, но они кажутся независимыми деревьями. После клона -f я попытался перебазировать --source E --dest D --detach, но он просто упал:(

Идеи?

Я знаю, что изменение истории сделает недействительным чей-либо клон репозиториев, в этом случае это не проблема. Все пользователи будут повторно клонировать в результате этих усилий.

3 ответа

Решение

РЕШИТЬ!

Первоначально я не заметил, что мой предполагаемый общий предок в конце концов не был тем же самым. Во время преобразования репозитория Foo в svn-> hg строки $ID$ были расширены, но не были созданы в репо Бар. Шаг 1 ниже был простым исправлением для создания РЕАЛЬНОГО общего предка.

Следующие шаги позволили мне достичь моей цели:

1- Убедитесь, что предполагаемый общий предок (D и D') фактически идентичен. Если нет, создайте новую точку сращивания для них (S) в репо Бар. S должен точно соответствовать содержанию D 'в моем примере.

... ABCD- JK---L
              \  \   /
               С МН

2- Обрезать историю репо Foo, чтобы удалить дубликат истории, в том числе D ', с

    hg convert --splicemap TrimSplicemap Foo FooTrimmed

Содержимое TrimSplicemap: (где E - полный хэш E)

    E 0000000000000000000000000000000000000000

3- Используйте полосу hg, чтобы удалить отключенную, избыточную историю

    CD FooTrimmed
    HG Strip C '

4- Снова используйте hg convert, чтобы соединить раздетое репо Фу с репо Баром при коммите 'S'

    кд../Бар
    hg convert --splicemap FooBarSplicemap ../FooTrimmed .

Содержимое FooBarSplicemap: (где E'это НОВЫЙ хеш для E в FooTrimmed, а S это хеш S)

    E'S

Это должно сделать это!:D

Мы говорили об этом сегодня в IRC, и мой совет состоял в том, чтобы просто втянуть обоих в один репо и позволить ему иметь два корня. Головы будут именно такими, как вы хотите, а остальное действительно не имеет значения.

Если вы просто не можете этого пережить (вы представляете, что люди используют историю / вину больше, чем они на самом деле), то я думаю, что ваша карта соединения должна иметь:

E D

в, так как вы пытаетесь заставить родителя E быть D (не D')

Вы могли бы сделать это, используя Mercurial Queues.

  1. Импортировать все изменения из репо Foo в очередь патчей.
  2. Перейти к Bar Сделки РЕПО.
  3. Обновить Bar на набор изменений, который является общим предком.
  4. Импортируйте очередь исправлений в Bar,
  5. Примените очередь исправлений.

Это изменит идентификаторы коммитов всех Foo патчи, но все же позволяют вам сохранять всю историю и объединять их репозитории.

Другие вопросы по тегам