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

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

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

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


CategoryTutorial

RussianTutorialConflict (last edited 2012-08-13 21:03:14 by 94-153-226-116-kv)