Очередной блог фрилансера

коротко и полезно о веб-разработке

Menu Close

Меркуриал. Разрешение конфликтов

В предыдущей статье, мы рассматривали совместную работу над одним проектом, изучив базовые приемы объединения двух различных репозиториев в один. В сегодняшней статье, мы рассмотрим более сложную ситуацию – разрешение конфликтующих изменений.Итак, как вы уже заметили ранее, большинство объединений выполняется очень просто, но из всякого правила бывают исключения. Иногда, вы можете столкнуться с тем, что каждая сторона изменений затрагивает одну и ту же часть, одного и того же файла. И если обе модификации не идентичны, то слияние приведет к образованию конфликта, в котором вам придется решить, каким образом «помирить» различные изменения, чтобы получить правильный результат.

Рисунок 3.4. Конфликтующие изменения документа

schema

Рисунок 3.4.  иллюстрирует пример двух конфликтующих изменений одного и того же документа. Мы начнем с создания первоначальной версии файла, затем произведем в нем небольшие изменения, в то время как кто-нибудь другой, изменит ту же часть текста. Наша задача в разрешении конфликтующих изменений – решить, как именно должен выглядеть наш файл после объединения.

Меркуриал не имеет встроенной возможности разрешения конфликтов. Вместо этого, он использует внешнюю программу, имеющую графический интерфейс.

Рабочий пример

В разрешении конфликтующих изменений нет ничего сложного, и сейчас мы на примере разберем эту задачу.

Первое, что нам понадобится – это исходный репозиторий с файлом, который мы впоследствии будем изменять. Создаем папку first, внутри которой, создаем простой текстовый файл, с именем letter.txt, с одним единственным, знакомым многим, предожением:

letter

Далее запускаем внутри папки командную строку, и поочередно выполняем следующие команды:

$ hg init

$ hg add letter.txt

$ hg commit –m “исходная версия текстового файла”

Здесь, мы сначала создаем репозиторий, затем добавляем в него наш файл letter.txt, и сохраняем его начальную версию. То же самое можно сделать с помощью графического интерфейса, через контекстное меню, доступное по правому клику мыши.

Далее, клонируем репозиторий first, в репозиторий под названием first-one. Снова используем командную строку:

$ cd ..

$hg clone first first-one

Если вы все сделали правильно, у вас должна появится новая папка с именем first-one, заходим в нее и смело изменяем копию файла letter.txt:

letter-two

Сохраняем изменения, и создаем новый коммит:

$ cd first-one

$ hg commit –m “название булок изменено на норвежские”

Отлично, наш первый репозиторий с изменениями готов. Теперь снова вернемся к изначальному репозиторию first, и клонируем его еще раз. В этот раз, имя клонированного репозитория будет first-second:

$ cd ..

$ hg clone first first-second

Заходим внутрь только что клонированного репозитория first-second, и снова изменяем копию файла letter.txt:

letter-three

И снова повторяем действия второго этапа, записываем наши изменения:

$ cd first-second

$ hg commit –m “название булок изменено на австрийские”

Отлично, теперь у нас есть две копии одного репозитория, с разными изменениями одной и той же части предложения. Переходим к главной части нашего примера – к объединению. Для того, чтобы не было путаницы, создадим из репозитория first-one клон, и назовем его first-merge. Он как раз и будет содержать объединенные версии двух репозиториев.

$ cd ..

$ hg clone first-one first-merge

$ cd first-merge

$ hg pull –u ../first-second

В вышеприведенном коде, кроме того что мы клонировали новый репозиторий first-merge, мы еще затянули в него изменения из репозитория first-second, так что сейчас он содержит два набора взаимоисключающих изменений. Теперь самое интересное, нам нужно их объединить, так что смело запускаем команду:

$ hg merge

И перед вами должна предстать графическая утилита Kdiff3, предназначенная специально для разрешения конфликтов:

kDiff3

Как раз, на представленном выше скриншоте, она сообщает нам, что у нас есть один конфликт, который не возможно разрешить автоматически. А нам и не нужно автоматически, поэтому жмем кнопку ОК, и внимательно смотрим на окошко:

kDiff3-2

Здесь по порядку слева направо отображается:

  • A —  набор изменений после которого началась развилка
  • B —  набор изменений, содержащийся в репозитории first-one
  • C — набор изменений, затянутый из репозитория first-second.

Итак, для того чтобы разрешить конфликтную ситуацию, нам нужно решить, какое же изменение стоит использовать в конечном итоге. Предположим, что свежие австрийские булки будут гораздо лучше на вкус, чем черствые норвежские, поэтому, мы решаем использовать набор изменений C, который был получен из репозитория first-second.

Для того чтобы использовать ревизию C, можно воспользоваться соответствующей кнопкой на панели инструментов, или пунктом меню «Merge – Select Line(s) from C»

kDiff3-merge

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

$ hg commit –m “объединение двух версий”

Теперь если воспользоваться командой контекстного меню «TortoiseHG – View Changelog», мы сможем увидеть как были объединены наши конфликтующие ветки:

changelog

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

В статье использовались материалы книги «Mercurial: The Definitive Guide«, автор Bryan O’Sullivan

Рассказать друзьям

Понравилась статья? Лучший способ сказать спасибо - поделиться ссылкой в социальных сетях: