3-way merge with meld

29 Oct 2013

Достаточно часто разработчики попадают в необходимость так называемого 3-way (трехстороннего) слияния. Разберем что тут и к чему.

В качестве DVCS у нас используется mercurial/hg, а для merge используем meld.

При 3-way merge выделяются следующие состояния:

  • local - новые локальные изменения, которые хотим протолкнуть
  • merged - стабильное (бесконфликтное) состояние репозитария
  • other - внешние изменения в репозитарии, которые вызвали конфликт

Для яcности эксперимента проверим это все на простом примере. Создадим директорию 3_way_merge_test. В ней создадим папки original и clone.

В папке original создадим файл test.txt Запишем в него “hello world”. Сделаем коммит.

Далее склонируем этот репозитарий в папку clone

hg clone ./original clone

В репозитарии clone отредактируем файл test.txt и добавим в конец строки “hello world” восклицательный знак. Закоммитим эти изменения и протолкнем в оригинальный репозитарий командой hg push.

Перейдем в оригинальный репозитарий original. Отредактируем в нем файл test.txt и в конец строки “hello world” добавим вопросительный знак. Закоммитим эти изменения.

Сразу после коммита mercurial напишет нам что создана новая “голова” в репозитарии. Это действительно так, если посмотреть вывод команды hg heads.

Попробуем разрешить эту ситуацию и сделать слияние голов. Выполним команду hg merge.

Т.к. в качестве merge tool в настройках .hgrc у меня указан meld, то для слияния сразу он и запустится. Таким образом в base у нас будет версия строки: “hello world?” В merged будет версия строки “hello world”. В other будет версия строки “hello world!”. Выберем из какой ветки нам взять изменения для merged и сохраним файлы при выходе из meld. Ну и делаем коммит с комментарием что это слияние

hg commit -m "merge"

Усложним эксперимент. Создадим папку original. В ней инициализируем пустой репозитарий командной hg init. В этой папке создадим файл test.txt. Запишем в него строчку “hello world”. Закоммитим это в репозитарий.

Склонируем этот репозитарий в папку test1 командной

hg clone ./original test1

Еще раз склонируем репозитарий в папку test2.

hg clone ./original test2

Зайдем в папку test2 и изменим в ней файл test.txt. Добавим в конец строки “hello world” восклицательный знак. Закоммитим изменения. Сделаем hg push.

Зайдем в папку test1 и изменим в ней файл test.txt. Добавим в конец строки “hello world” вопросительный знак. Закоммитим изменения. Делаем hg pull.

Получаем опять 2 “головы” и необходимость слияния. Выполняем hg merge.

В итоге получаем следующие выводы:

  • local: hello world?
  • merged: hello world
  • other: hello world!

Надеюсь эта информация была для вас полезной и поможет в работе.


comments powered by Disqus