Управление версиями в Subversion Для Subversion 3 (в редакции 2345) Бен Коллинз-Сассман



бет13/34
Дата04.03.2016
өлшемі2.13 Mb.
#40691
түріРеферат
1   ...   9   10   11   12   13   14   15   16   ...   34

Что такое ветка?


Предположим, что ваша работа заключается в сопровождении документа, например какого-то руководства, для подразделений в вашей компании. Однажды различные подразделения запросят у вас одно и тоже руководство, но с несколькими частями которые будут немного «подредактированны», так как задачи у них немного различаются.

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

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

В этом заключается основная идея ветки — а именно, направления разработки, которое существует независимо от другого направления, однако имеющие с ним общую историю, если заглянуть немного в прошлое. Ветка всегда берет начало как копия чего-либо и двигается от этого момента создавая свою собственную историю (см. Рисунок 4.1, «Ветки разработки»).



Рисунок 4.1. Ветки разработки

У Subversion есть команды, которые помогают сопровождать параллельные ветки файлов и директорий. Эти команды позволяют создавать ветки, копируя информацию и запоминая, что копии относятся друг к другу. Кроме того эти команды помогают дублировать изменения из одной ветки в другую. Наконец, они могут сделать отдельные части рабочей копии отвечающими отдельным веткам, что позволит вам «смешивать и согласовывать» различные направления разработки в своей каждодневной работе.


Использование веток


К этому моменту вы должны понимать как в хранилище, при каждой фиксации, создается полностью новое дерево файлов (называемое «правка»). Если нет, то вернитесь назад и прочитайте раздел «Правки».

Для этой главы, мы воспользуемся тем же примером, что и в Главе 2. Как вы помните, вы и ваш соразработчик Салли делите хранилище, содержащее два проекта, paint и calc. Как показывает Рисунок 4.2, «Начальная структура хранилища» каждая директория проекта содержит поддиректории с названиями trunk и branches. Назначение этих директорий скоро станет понятно.



Рисунок 4.2. Начальная структура хранилища

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

Скажем, перед вами была поставлена задача коренной реорганизации проекта. Это займет много времени и затронет все файлы проекта. Проблема заключается в том, что вы не хотите мешать Салли, которая прямо сейчас занимается исправлением небольших ошибок. Ее работа зависит от постоянной доступности последней версии проекта (директории /calc/trunk). Если вы начнете пошагово фиксировать свои изменения, вы конечно же смешаете Салли все карты.

Одним из вариантов является ограничение свободы действий: вы и Салли перестаете делиться информацией на неделю или две. В это время начинайте переворачивать и реорганизовывать файлы рабочей копии, но не фиксируйте и не обновляйте ее пока не закончите эту задачу. Однако в этом случае появляется несколько проблем. Во-первых это не очень надежно. Большинство людей предпочитают часто сохранять свою работу в хранилище, на случай если вдруг что-то плохое случится с рабочей копией. Во-вторых, это не достаточно гибко. Если вы работаете на разных компьютерах (к примеру если рабочая копия /calc/trunk есть у вас на разных машинах), вам придется вручную копировать изменения взад и вперед, либо делать всю работу на одном компьютере. А с другой стороны, вам трудно разделять вносимые изменения с кем-то еще. Общий при разработке программного обеспечения «лучший метод организации» это возможность совместного просмотра проделанной работы по мере продвижения. Если никто не видит ваших промежуточных фиксаций, вы теряете потенциальную возможность обратной связи. В конце концов, когда вы закончите свои изменения, вы можете обнаружить, что очень трудно заново слить сделанную вами работу с остальным программным кодом компании. Салли или (кто-то другой) могли внести изменения в хранилище, которые будет трудно внедрить в вашу рабочую копию — особенно если вы выполните svn update после нескольких недель изоляции.

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

Создание ветки


Создать ветку очень просто — при помощи команды svn copy делаете в хранилище копию проекта. Subversion может копировать не только отдельные файлы но и директории. Итак, вам нужно сделать копию директории /calc/trunk. Где эта новая копия будет находится? Где угодно — этот вопрос определяется правилами проекта. Допустим, что правилами вашей команды определено создание веток в директории /calc/branches хранилища, и свою ветку вы хотите назвать my-calc-branch. Вам необходимо создать новую директорию /calc/branches/my-calc-branch которая будет являться копией /calc/trunk.

Есть два способа создания копии. Сначала мы покажем неудачный способ, просто для того, что бы прояснить основные моменты. Для начала, создается рабочая копия корневой директории проекта /calc:

$ svn checkout http://svn.example.com/repos/calc bigwc

A bigwc/trunk/

A bigwc/trunk/Makefile

A bigwc/trunk/integer.c

A bigwc/trunk/button.c

A bigwc/branches/

Checked out revision 340.

Теперь создание копии заключается в простой передаче двух путей в пределах рабочей копии команде svn copy:

$ cd bigwc

$ svn copy trunk branches/my-calc-branch

$ svn status

A + branches/my-calc-branch

В этом случае, команда svn copy рекурсивно копирует рабочую директорию trunk в новую рабочую директорию branches/my-calc-branch. Теперь команда svn status покажет, что новая директория запланирована для добавления в хранилище. Обратите внимание на знак «+» после буквы А. Это означает, что то что запланировано для добавления является копией чего-то, а не чем-то новым. При следующей фиксации, Subversion создаст в хранилище путем копирования директории /calc/trunk директорию /calc/branches/my-calc-branch, вместо повторного отправления через сеть всей информации рабочей копии:

$ svn commit -m "Creating a private branch of /calc/trunk."

Adding branches/my-calc-branch

Committed revision 341.

А теперь, простой способ создания ветки, о котором мы говорили раньше: команда svn copy может оперировать с двумя URL напрямую.

$ svn copy http://svn.example.com/repos/calc/trunk \

http://svn.example.com/repos/calc/branches/my-calc-branch \

-m "Creating a private branch of /calc/trunk."


Committed revision 341.

В сущности, между этими двумя методами нет разницы. Оба варианта создают в правке 341 новую директорию и эта новая директория является копией /calc/trunk. Это показывает Рисунок 4.3, «Хранилище, содержащее новую копию». Обратите внимание на то, что второй метод, кроме прочего, выполняет немедленную фиксацию. [13]Эта процедура более проста в использовании, так как нет необходимости в создании рабочей копии, отражающей большое хранилище. Фактически, в этом случае вам вовсе можно не иметь рабочей копии.



Рисунок 4.3. Хранилище, содержащее новую копию



Легкие копии

Хранилище Subversion спроектировано особым образом. При копировании директории, нет необходимости задумываться о большом увеличении размера хранилища — на самом деле Subversion никогда не дублирует информацию. Вместо этого, создается новая сущность директории, которая указывает на существующие дерево файлов. Если вы пользователь Unix, это тот же подход, что используется для жестких ссылок. То есть копия, так сказать, стала «ленивой». Это значит, что если вы зафиксируете изменения одного файла из скопированной директории, то изменится только этот файл — остальные файлы будут продолжать существовать как ссылки на первоначальные файлы в первоначальной директории.

Вот почему часто в разговоре пользователей Subversion можно услышать о «легких копиях». Не имеет значения, насколько директория большая — для создания копии требуется очень небольшой фиксированный промежуток времени. Фактически, на этой функции основана работа фиксаций в Subversion: каждая правка является «легкой копией» предыдущей правки, с несколькими элементами лениво измененными в ней. (Что бы прочитать больше об этом, посетите веб сайт Subversion и прочитайте в документах по архитектуре Subversion о методе «всплывающих пузырьков».)

Конечно, эти внутренние механизмы копирования и деления информации скрыты от пользователя, который видит просто копии файлов. Основное здесь, это то, что копии легкие как по времени, так и по размеру. Делайте ветки так часто, как вам необходимо.


Работа с веткой


После создания ветки проекта, можно создать новую рабочую копию для начала ее использования:

$ svn checkout http://svn.example.com/repos/calc/branches/my-calc-branch

A my-calc-branch/Makefile

A my-calc-branch/integer.c

A my-calc-branch/button.c

Checked out revision 341.

В этой рабочей копии нет ничего особенного; она является просто отражением другой директории хранилища. Когда вы фиксируете изменения, то если Салли сделает обновление, она их даже не увидит. Ее рабочая копия является копией /calc/trunk. (Прочтите далее в этой главе раздел «Переключение рабочей копии»: команда svn switch является альтернативным способом создания рабочей копии ветки.)

Предположим, что прошла неделя и были сделаны следующие фиксации:



  • Вы внесли изменения в /calc/branches/my-calc-branch/button.c, с созданием правки 342.

  • Вы внесли изменения в /calc/branches/my-calc-branch/integer.c, с созданием правки 343.

  • Салли внесла изменения в /calc/trunk/integer.c, с созданием правки 344.

Теперь есть два независимых направления разработки файла integer.c, которые показывает Рисунок 4.4, «История ветвления для одного файла».

Рисунок 4.4. История ветвления для одного файла

Если посмотреть историю сделанных изменений для вашей копии integer.c, можно увидеть интересные вещи:

$ pwd

/home/user/my-calc-branch


$ svn log --verbose integer.c

------------------------------------------------------------------------

r343 | user | 2002-11-07 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines

Changed paths:

M /calc/branches/my-calc-branch/integer.c
* integer.c: frozzled the wazjub.
------------------------------------------------------------------------

r341 | user | 2002-11-03 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines

Changed paths:

A /calc/branches/my-calc-branch (from /calc/trunk:340)


Creating a private branch of /calc/trunk.
------------------------------------------------------------------------

r303 | sally | 2002-10-29 21:14:35 -0600 (Tue, 29 Oct 2002) | 2 lines

Changed paths:

M /calc/trunk/integer.c


* integer.c: changed a docstring.
------------------------------------------------------------------------

r98 | sally | 2002-02-22 15:35:29 -0600 (Fri, 22 Feb 2002) | 2 lines

Changed paths:

M /calc/trunk/integer.c


* integer.c: adding this file to the project.
------------------------------------------------------------------------

Обратите внимание на то, что Subversion прослеживает историю ветки integer.c во времени полностью, в том числе пересекая точку создания копии. Создание ветки показывается как событие в истории, потому что файл integer.c был неявно скопирован, при копировании всей директории /calc/trunk/. Теперь давайте посмотрим, что будет когда такую же команду Салли выполнит для своей копии файла:

$ pwd

/home/sally/calc


$ svn log --verbose integer.c

------------------------------------------------------------------------

r344 | sally | 2002-11-07 15:27:56 -0600 (Thu, 07 Nov 2002) | 2 lines

Changed paths:

M /calc/trunk/integer.c
* integer.c: fix a bunch of spelling errors.
------------------------------------------------------------------------

r303 | sally | 2002-10-29 21:14:35 -0600 (Tue, 29 Oct 2002) | 2 lines

Changed paths:

M /calc/trunk/integer.c


* integer.c: changed a docstring.
------------------------------------------------------------------------

r98 | sally | 2002-02-22 15:35:29 -0600 (Fri, 22 Feb 2002) | 2 lines

Changed paths:

M /calc/trunk/integer.c


* integer.c: adding this file to the project.
------------------------------------------------------------------------

Салли увидит свои собственные изменения правки 344, а ваши сделанные в правке 343 нет. Subversion позаботилась о том, что бы эти две фиксации затронули разные файлы, имеющие разное расположение в хранилище. Тем не менее, Subversion будет показывать то, что два файла имеют одну историю. До создания в правке 341 ветки (или копии) это был один файл. Поэтому и вы и Салли видите изменения сделанные в правке 303 и 98.


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


Два важных понятия, которые вы должны запомнить из этого раздела.

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

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


Достарыңызбен бөлісу:
1   ...   9   10   11   12   13   14   15   16   ...   34




©dereksiz.org 2024
әкімшілігінің қараңыз

    Басты бет