Учебник - Слияние конфликтующих Изменений
(Этот раздел является частью Учебника. Предыдущий раздел - Слияние изменений, следующий раздел - Заключение)
Мы научились, как пользоваться простым слиянием в разделе RussianTutorialMerge.
Mercurial способен справиться и с более сложными случаями слияния. Нечасто встречается ситуация, когда двое людей редактируют в точности одну и ту же строку файла, а затем должны выяснить, как выходить из этой ситуации. Подобные случаи называются конфликтами; выяснение, что делать с конфликтом, называется разрешением этого конфликта.
Давайте сперва создадим искусственную конфликтную ситуацию. Как мы делали до этого, давайте начнем с создания клона my-hello:
$ cd .. $ hg clone my-hello my-hello-not-cvs updating working directory 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
Теперь давайте добавим новую строку вывода в hello.c:
$ cd my-hello-not-cvs $ vi hello.c
Мы меняем main следующим образом:
int main(int argc, char **argv)
{
printf("hello, world!\n");
printf("sure am glad I'm not using CVS!\n");
return 0;
}
и фиксируем изменение:
$ hg commit -m "Give thanks for dodging bullet"
Напомним, что в разделе "Создание первого изменения" мы создали набор изменений в my-hello-new-output, который также добавлял вторую строку вывода. Что произойдет, когда мы попытаемся подтянуть это изменение в наш репозитарий?
$ hg pull ../my-hello-new-output pulling from ../my-hello-new-output searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge)
Ну, пока все хорошо. Давайте попробуем обновить.
$ hg update abort: crosses branches (use 'hg merge' or 'hg update -C')
Как и в разделе "Слияние изменений", мы должны запустить hg merge. В данном случае невозможно будет произвести слияние автоматически, потому что одна и таже строка одного и того же файла была модифицирована различным образом в каждом из двух наборов изменений (один мы только что зафиксировали, а другой только что подтянули).
$ hg merge
То, что произойдет в результате этой команды, зависит от настроек Mercurial (см. MergeToolConfiguration). По умолчанию Mercurial добавит набор маркеров в конфликтные файлы в Вашей рабочей копии:
/* * hello.c * * Placed in the public domain by Bryan O'Sullivan * * This program is not covered by patents in the United States or other * countries. */ #include <stdio.h> int main(int argc, char **argv) { printf("hello, world!\n"); <<<<<<< local printf("sure am glad I'm not using CVS!\n"); ======= printf("sure am glad I'm using Mercurial!\n"); >>>>>>> other return 0; }
Вы можете найти эти файлы, использую команду 'hg status'. Как и прежде, Mercurial сохранит копии исходных файлов, перед тем, как вставлять маркеры конфликта:
$ hg status M hello.c ? hello.c.orig
Чтобы разрешить этот конфликт, мы открываем 'hello.c' в редакторе, удаляем маркеры конфликта и сохраняем строку "sure am glad I'm using Mercurial!\n", удаляя при этом служебные строки. Затем сохраняем файл и выходим из редактора.
Далее даём знать Mercurial'у, что мы разрешили конфликт, с помощью команды hg resolve:
$ hg resolve -m hello.c
Mercurial без лишних слов принимает такой вариант.
Как и прежде, обязательно зафиксируйте это изменение в репозитарии, раз уж слияние завершено:
$ hg commit -m "Merged changes from my-hello-new-output"
То, что описано в данном разделе, является поведением Mercurial по умолчанию. Вы можете, если захотите, настроить Mercurial, чтобы он открывал редактор автоматически. Mercurial может также вызывать внешние инструменты для трехстороннего слияния. Информацию о вариантах настройки можно найти в MergeToolConfiguration.
Теперь давайте завершим обучение в разделе Заключение.