Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab4.doc
Скачиваний:
22
Добавлен:
02.04.2015
Размер:
712.7 Кб
Скачать

3.5 Ключевые идеи, стоящие за ветками

Из этого раздела вы должны запомнить две вещи.

  1. В отличие от многих других систем управления версиями, в хранилище Subversion ветки существуют не в отдельном измерении, а как обычные каталоги файловой системы. Эти каталоги отличаются только тем, что несут дополнительную информацию о своей истории.

  2. Subversion не имеет такого понятия как ветка — есть только копии. Копия каталога становится «веткой» только потому, что вы рассматриваете ее таким образом. Вы можете по-разному думать о каталоге, по разному его трактовать, но для Subversion это не более чем обычный каталог, созданный в результате копирования.

3.6 Копирование изменений между ветками

Теперь вы и Салли работаете над параллельными ветками проекта: вы — над своей собственной веткой, а Салли — над главной линией разработки (каталогtrunk).

В проектах со значительным числом участников, как правило, большинство работает в главной линии разработки. Когда кому-то необходимо сделать изменения, которые займут много времени и могут нарушить главную линию, стандартной практикой является создание отдельной ветки и фиксация всех изменений в ней — до тех пор, пока работа не будет полностью завершена.

Положительным моментом здесь является то, что вы и Салли не пересекаетесь друг с другом. Но есть и минус — вы можете разойтись слишком далеко друг относительно друга. Помните, что одна из проблем такой стратегии «временной изоляции» заключается в том, что к моменту, когда вы завершите работу со своей веткой, может оказаться практически невозможным объединить ее с главной линией без огромного количества конфликтов.

Вместо этого вы и Салли можете продолжать делиться изменениями по ходу работы. Вы можете решать вплоть до отдельного изменения, стоит ли им делиться — Subversion предоставляет возможность выборочного «копирования» изменений между ветками. А тогда, когда вы полностью закончите работу со своей веткой, вы можете скопировать обратно в основную ветку все изменения полностью.

3.7 Копирование отдельных изменений

В предыдущем разделе мы отметили, что и вы, и Салли, одновременно, в разных ветках вносите изменения в файл integer.c. Если посмотреть на лог-сообщение Салли для правки 344, вы увидите, что она исправила несколько орфографических ошибок. Конечно же, в вашей копии этого файла эти ошибки остались. Не исключено, что ваши будущие изменения этого файла коснутся областей, содержащих эти орфографические ошибки, и таким образом вы получите несколько потенциальных конфликтов при последующем объединении вашей ветки. Поэтому лучше получить изменения от Салли сейчас, до того, как вы начнете вплотную работать с этой частью файла.

Настал момент воспользоваться командой svn merge. Эта команда, оказывается, является очень близким родственником команды svn diff (о которой вы читали в Глава 2, Экскурсия по Subversion). Обе команды способны сравнивать любые два объекта в хранилище и показывать различия. Например, вы можете попросить svn diff показать все изменения, сделанные Салли в правке 344:

$ svn diff -r 343:344 http://svn.example.com/repos/calc/trunk

Index: integer.c

===================================================================

--- integer.c (revision 343)

+++ integer.c (revision 344)

@@ -147,7 +147,7 @@

case 6: sprintf(info->operating_system, "HPFS (OS/2 or NT)"); break;

case 7: sprintf(info->operating_system, "Macintosh"); break;

case 8: sprintf(info->operating_system, "Z-System"); break;

- case 9: sprintf(info->operating_system, "CPM"); break;

+ case 9: sprintf(info->operating_system, "CP/M"); break;

case 10: sprintf(info->operating_system, "TOPS-20"); break;

case 11: sprintf(info->operating_system, "NTFS (Windows NT)"); break;

case 12: sprintf(info->operating_system, "QDOS"); break;

@@ -164,7 +164,7 @@

low = (unsigned short) read_byte(gzfile); /* read LSB */

high = (unsigned short) read_byte(gzfile); /* read MSB */

high = high << 8; /* interpret MSB correctly */

- total = low + high; /* add them togethe for correct total */

+ total = low + high; /* add them together for correct total */

info->extra_header = (unsigned char *) my_malloc(total);

fread(info->extra_header, total, 1, gzfile);

@@ -241,7 +241,7 @@

Store the offset with ftell() ! */

if ((info->data_offset = ftell(gzfile))== -1) {

- printf("error: ftell() retturned -1.\n");

+ printf("error: ftell() returned -1.\n");

exit(1);

}

@@ -249,7 +249,7 @@

printf("I believe start of compressed data is %u\n", info->data_offset);

#endif

- /* Set postion eight bytes from the end of the file. */

+ /* Set position eight bytes from the end of the file. */

if (fseek(gzfile, -8, SEEK_END)) {

printf("error: fseek() returned non-zero\n");

Команда svn merge ведет себя практически идентично. Но вместо вывода различий на терминал она применяет их к рабочей копии в виде локальных изменений:

$ svn merge -r 343:344 http://svn.example.com/repos/calc/trunk

U integer.c

$ svn status

M integer.c

Вывод команды svn merge показывает, что к вашей копии integer.c был применен патч. Теперь она содержит изменения Салли — они были «скопированы»из главной линии разработки в вашу рабочую копию, вашу собственную ветку, и теперь существуют в виде локальных изменений. С этого момента вы можете просмотреть локальные изменения и убедиться в том, что они корректны.

Возможна ситуация, когда не все будет так хорошо и integer.c окажется в состоянии конфликта. Тогда вам будет необходимо разрешить конфликт обычным путем (см. Глава 2, Экскурсия по Subversion), либо, если вы придете к мнению, что объединение было плохой идеей, просто отказаться от него, отменив локальные изменения командой svn revert.

Просмотрев результат объединения исправлений, его можно зафиксировать как обычно (svn commit). После этого изменения будут внесены в вашу ветку хранилища. В терминологии управления версиями такую процедуру копирования изменений между ветками обычно называют портированием изменений.

При фиксации локальных изменений убедитесь, что в лог-сообщении упоминается о портировании отдельных изменений из одной ветки в другую. Например:

$ svn commit -m "integer.c: ported r344 (spelling fixes) from trunk."

Sending integer.c

Transmitting file data .

Committed revision 360.

Как вы увидите в последующих разделах, очень важно следовать этой «хорошей практике».

Небольшое предупреждение: несмотря на то, что svn diff и svn merge по сути очень похожи, во многих случаях они используют разный синтаксис. Обязательно прочтите об этом в Глава 9, Полное справочное руководство по Subversion, или спросите у svn help. Например, svn merge требует в качестве целевого объекта путь в рабочей копии, то есть место, где ей нужно применить изменения структуры файлов. Если целевой объект не указан, предполагается, что делается попытка выполнить одну из следующих операций:

  1. объединение изменений каталога с вашим текущим рабочим каталогом;

  2. объединение изменений в конкретном файле с файлом, имеющим то же имя в текущем рабочем каталоге.

Если вы объединяете каталог и не указываете целевой путь, svn merge предполагает первый из приведенных выше вариантов и пытается применить изменения к текущему каталогу. Если вы объединяете файл, и при этом файл с таким именем есть в текущем рабочем каталоге, svn merge подразумевает второй случай и пытается применить изменения к локальному файлу с таким же именем.

Если вы хотите применить изменения к чему-то другому, вам нужно это указать. Например, если вы находитесь в родительском каталоге рабочей копии, то вам нужно указать целевой каталог, получающий изменения:

$ svn merge -r 343:344 http://svn.example.com/repos/calc/trunk my-calc-branch

U my-calc-branch/integer.c

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