Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
hgbook.pdf
Скачиваний:
50
Добавлен:
17.03.2015
Размер:
3.15 Mб
Скачать

Глава 3. Экскурсия по Mercurial: слияние результатов работы

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

3.1. Слияние потоков работы

Слияние — это основная часть работы с инструментами распределённого контроля версий. Вот несколько случаев, когда возникает необходимость объединить работу:

Элис и Боб имеют собственные репозитории проекта, над которым они вместе работают. Элис пофиксила ошибку в своем репозитории, а Боб добавил новую фичу в своём. Они хотят чтобы общий репозиторий содержал и багфикс и новую фичу.

Синтия часто работает в одном проекте одновременно над несколькими разными задачами, каждая из которых изолирована в собственном репозитории. Работая таким образом, приходится частенько производить слияние одной части работы с другой.

Поскольку слияние очень частая операция, Mercurial имеет простые средства её осуществления. Давайте рассмотрим процесс слияния. Начнем с еще одного клонирования репозитория (заметили насколько часто мы это делаем?) и внесения изменений в него.

$ cd ..

$ hg clone hello my-new-hello updating to branch default

2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd my-new-hello

# Make some simple edits to hello.c. $ my-text-editor hello.c

$ hg commit -m 'A new hello for a new day.'

Теперь у нас есть две копии hello.c c разным содержимым. История изменения этих двух репозиториев тоже различается, как показано на Рисунок 3.1, «Расхождение историй репозиториев my-hello и my-new-hello». Вот копия нашего файла из одного репозитория:

$ cat 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("once more, hello.\n"); printf("hello, world!\"); printf("hello again!\n"); return 0;

}

А здесь немного отличающаяся копия из другого хранилища:

$ cat ../my-hello/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.

*/

25

Экскурсия по Mercurial: слияние результатов работы

#include <stdio.h>

int main(int argc, char **argv)

{

printf("hello, world!\"); printf("hello again!\n"); return 0;

}

Рисунок 3.1. Расхождение историй репозиториев my-hello и my-new-hello

Мы уже знаем, что получение изменений из репозитория my-hello не изменит состояния рабочего каталога.

$ hg pull ../my-hello pulling from ../my-hello 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 pull говорит что-то о «головах» (heads), мол их стало на одну больше (+1 heads).

3.1.1. Головная ревизия

Напомним, что каждая ревизия в Mercurial, имеет родительскую ревизию. Если у ревизии есть родитель, мы называем её потомком. У головной (head) ревизии нет потомков. Главная (tip) ревизия тоже головная, потому что самая свежая ревизия в хранилище не может иметь потомков. Случаются моменты, когда репозиторий может содержать более одной головной ревизии.

26

Экскурсия по Mercurial: слияние результатов работы

Рисунок 3.2. Содержимое хранилища my-new-hello после получения изменений из myhello

На Рисунок 3.2, «Содержимое хранилища my-new-hello после получения изменений из my-hello» показан результат получения изменений из my-hello в my-new-hello. История, уже имеющаяся в my-new-hello не затронута, но добавлена новая ревизия. По сравнению с Рисунок 3.1, «Расхождение историй репозиториев my-hello и my-new-hello», видно, что ID ревизии остался прежним, а номер ревизии изменён. (Это, кстати, хороший пример, почему использование номеров ревизий при обсуждении наборов изменений не надёжно) Посмотреть головы в хранилище позволяет команда hg heads.

$ hg heads

 

changeset:

6:c3e3be994861

tag:

tip

parent:

4:2278160e78d4

user:

Bryan O'Sullivan <bos@serpentine.com>

date:

Thu Feb 02 14:10:17 2012 +0000

summary:

Added an extra line of output

changeset:

5:2908f9fcaad4

user:

Bryan O'Sullivan <bos@serpentine.com>

date:

Thu Feb 02 14:10:23 2012 +0000

summary:

A new hello for a new day.

 

 

3.1.2. Выполнение слияния

Что произойдёт, если мы попытаемся выполнить обычную команду hg update для обновления до новой головной ревизии?

$ hg update

abort: crosses branches (merge branches or update --check to force update)

Mercurial говорит нам, что команда hg update не выполняет слияния. Она думает, что мы ожидаем слияния, и не обновит рабочий каталог, если мы не принудим её к этому. (В данном случае, принудительное обновление с помощью hg update -C удалит все не сохраненные изменения в рабочем каталоге).

Для объединения двух голов мы воспользуемся командой hg merge.

$ hg merge merging hello.c

27

Экскурсия по Mercurial: слияние результатов работы

0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit)

Произошло слияние содержимого файла hello.c. Это привело к обновлению рабочего каталога — он теперь содержит изменения от обоих голов, что будет отражено в выводе hg parents и в содержании файла hello.c.

$ hg parents

 

changeset:

5:2908f9fcaad4

user:

Bryan O'Sullivan <bos@serpentine.com>

date:

Thu Feb 02 14:10:23 2012 +0000

summary:

A new hello for a new day.

changeset:

6:c3e3be994861

tag:

tip

parent:

4:2278160e78d4

user:

Bryan O'Sullivan <bos@serpentine.com>

date:

Thu Feb 02 14:10:17 2012 +0000

summary:

Added an extra line of output

$ cat 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("once more, hello.\n"); printf("hello, world!\"); printf("hello again!\n"); return 0;

}

3.1.3. Фиксация результатов слияния

Каждый раз, когда мы делаем слияние, hg parents показывает двух родителей пока мы не закрепим результат командой hg commit.

$ hg commit -m 'Merged changes'

Теперь у нас есть новая главная ревизия. Заметим, что обе бывшие головы теперь родители. Это те же ревизии, что раньше отображались командой hg parents.

$ hg tip

 

changeset:

7:45b2a02b6844

tag:

tip

parent:

5:2908f9fcaad4

parent:

6:c3e3be994861

user:

Bryan O'Sullivan <bos@serpentine.com>

date:

Thu Feb 02 14:10:24 2012 +0000

summary:

Merged changes

 

 

На Рисунок 3.3, «Рабочий каталог и репозиторий во время и после совершения слияния» вы можете увидеть представление того, что происходит с рабочим каталогом при слиянии, и как это влияет на хранилище, когда происходит коммит. Во время слияния, рабочий каталог состоял из двух родительских ревизий, и они стали родителями новой ревизии.

28

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]