Учебник - Слияние конфликтующих Изменений

(Этот раздел является частью Учебника. Предыдущий раздел Слияние изменений, следующий раздел Заключение)

Мы научились, как пользоваться простым слиянием в разделе 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", удаляя при этом про CVS. Мы можем затем сохранить файл и выйти из редактора.

Заетем, мы даем знать Mercurial'у, что мы разрешили конфлик, использую комманду hg resolve:

$ hg resolve -m hello.c

Mercurial принемает решение без какого-либо уведомления.

Как и прежде, обязательно зафиксируйте это изменение в репозитарии, раз уж слияние завершено:

$ hg commit -m "Merged changes from my-hello-new-output"

То, что мы увидели в данном разделе является поведением Mercurial'а по умолчанию. Вы можете, если захотите, сконфигурировать Mercurial, чтобы он открывал редактор автоматически. Mercurial может также быть сконфигурирован вызывать внешние инструменты для трехстороннего слияния. Информацию об обоих вариантах конфигурирования можно найти в MergeToolConfiguration.

Теперь, давайте продолжим и завершим обучение в разделе Заключение.


CategoryTutorial