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

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

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

To resolve the conflict, we open 'hello.c' in an editor, delete the conflict markers and keep the "sure am glad I'm using Mercurial!\n" line, deleting the line about CVS. We can then save and quit the editor.

Then, we let Mercurial know that we have resolved the conflict using the hg resolve command:

$ hg resolve -m hello.c

Mercurial accepts the resolution without any output.

As before, be sure to commit this change to the repository once the merge is complete:

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

What we have seen here is the default behaviour of Mercurial. You can, if you want, configure Mercurial to open the editor automatically. Mercurial can also be configured to call external three-way merge tools. Information about both of these can be found at MergeToolConfiguration.

Now let's continue and finish on to TutorialConclusion.


CategoryTutorial