SVN для чайников. Часть III.

Работа с ветвлениями

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

Также часто возникают ситуации, когда при работе над проектом, появляется мысль, реализация и проверка которой займет больше чем день. В этом случае работа в основной ветке может привести к получению нерабочего проекта в ней или к созданию помех коллегам, которые работают вместе с вами над проектом.
Очень распространенная ситуация это создание готовых слепков — релизов проекта. Т.е. сохранения состояния проекта в отдельное место, после которого файлы проекта в этом месте меняться не будут. Можно это сделать с помощью команды Export и хранения проекта в специальном месте, но в этом случае история проекта, которая храниться в SVN, будет оторвана от релиза. И если в релизе будут найдены ошибки, которые не были замечены ранее, потребуется вручную их поправить во всех копиях проекта.

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

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

./                 корневой каталог репозитория
    Project0
        branch     ветки проекта Project0
        tag        метки (ревизии) проекта Project0
        trunk      ствол (основное направление разработки) проекта Project0
    Project1
        branch     ветки проекта Project1
        tag        метки(ревизии) проекта Project1
        trunk      ствол (основное направление разработки) проекта Project1

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

Совет. Помните trunk/branch/tag это самые обычные папки, они не предписывают и не ограничивают использование репозитория SVN. Эти папки всего лишь помечают место, которое отводиться разработчику для работы над проектом. Т.е. папка branch это всего лишь рекомендованное место, где разработчик может проводить свои изыскания, папка tag это рекомендованное место для хранения релизов проекта. Никто не запрещает вам хранить релизы и проводить изыскания в других папках репозитория, но для упорядочивания репозитория лучше придерживаться правил хорошего тона.

Рассмотрим основные ситуации, возникающие при работе с ветвлениями.

Создание меток и веток (tag и branch)

Вернемся опять к нашим разработчикам Васе и Пете. Они закончили свой проект и теперь решили выпустить метку (tags) – релиз данного проекта под номером 1.0. Для этого нужно воспользоваться командой Branch/Tag (рис. 61).

Затем нужно указать полное имя места назначения метки и номер ревизии основного проекта для которого создается метка. В данном примере метка создается в папке tags/release_1.0 и источником является последняя ревизия проекта demo_project1 находящаяся в репозитории(рис. 62).

Создание ветки производится точно таким же образом, но ветки создаются в директории branch (рис. 63). После этих действий состояние репозитория следующее (рис. 64).

Рис. 61. Создание ветки/метки проекта в репозитории
Рис. 61. Создание ветки/метки проекта в репозитории

Рис. 62. Диалоговое окно выбора настроек создания метки проекта
Рис. 62. Диалоговое окно выбора настроек создания метки проекта

Рис. 63. Диалоговое окно выбора настроек создания ветки проекта
Рис. 63. Диалоговое окно выбора настроек создания ветки проекта

Рис. 64. Состояние репозитория после создания метки и ветки проекта
Рис. 64. Состояние репозитория после создания метки и ветки проекта

Важное замечание. Перед тем как делать ответвление от проекта обязательно синхронизируйте свою рабочую копию с репозиторием командой Update. Но если вы внесли множество изменений в основную ветку и не хотите их фиксировать в основной ветке (например, проект не отлажен), то можно сделать branch, опираясь на состояние рабочей копии, а не репозитория. В этом случае будет создана ветка, в которой будут зафиксированы все изменения.

Подсказка. Если вы выпустили релиз проекта, а в нем обнаружена ошибка, не устраняйте ее метках (tags). Используйте один из двух вариантов.

  1. Если нужно только устранить ошибку, то скопируйте метку(tag) в ветку (branch). Устраните ошибку, сделайте новую метку, удалите ветку.
  2. Если устранение ошибки совмещено с модернизацией проекта, то выпустите новый релиз проекта.

Подсказка. Узнать к какому репозиторию, проекту и ветке относиться папка/файл можно из свойств папки/файла, которая находиться под контролем репозитория.

Переключение рабочей копии между ветками

Переключение между любыми ветвлениями выполняется командой Switch (рис. 65). В качестве параметра нужно указать путь к проекту в репозитории, на который нужно сделать переключение рабочей копии (рис. 66). При работе с командой Switch нужно помнить о следующем:

  1. Файлы, которые находятся под контролем SVN, при переключении ветки заменяются на соответствующие файлы из другой ветки. Если файл присутствует только в одной из веток, то соответственно он будет автоматически удаляться и появляться (это нормальная работа данной команды, нет повода для беспокойства).
  2. Изменения в рабочей копии обладают приоритетом перед состоянием файлов в репозитории. Если перед переключением вы их не зафиксировали, они останутся в рабочей копии. Если переключения происходят часто, то можно случайно зафиксировать эти изменения не в ту ветку разработки.

Рис. 65. Переключение рабочей копии на другую ветку разработки
Рис. 65. Переключение рабочей копии на другую ветку разработки

Рис. 66. Диалоговое окно выбора ветки на которую нужно переключиться
Рис. 66. Диалоговое окно выбора ветки на которую нужно переключиться

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

Слияние ветвлений

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

Эти действия в SVN выполняются с использованием команды Merge. Слить ветки можно только в рабочей копии одной из веток. При этом результат слияния будет в рабочей копии и в случае ошибок слияния этот результат можно отменить командой Revert.

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

При слиянии веток нужно помнить о следующем:

  1. При обычном слиянии файл не замещается другим файлом. Файл рассматривается как набор строк. Итоговый файл составляется из строк файлов, которые участвовали в процессе слияния. Поэтому если бинарный файл будет обрабатываться как текстовый, то результирующий файл будет не работоспособен.
  2. Переименование файла в SVN реализовано через механизм Copy/Delete поэтому новый файл логически не связан со старым (кроме общей истории). И после слияния веток в проекте будут оба файла. Избегайте необдуманного переименования файлов и учитывайте переименование при слияниях.

Рассмотрим процесс слияния demo_project1 и его ветки demo_branch. Положим, что Вася работает с веткой demo_branch, вносит изменения в файл hello.py и добавляет к проекту файл define.py. Петя в свою очередь работает в основной ветке разработки trunk и вносит изменения в файлы hello.py и bye.py. Перед слиянием состояние рабочих копий Васи и Пети следующее (рис. 67).

Вася и Петя фиксируют изменения в репозитории. Вася сообщает Пете, что закончил тестирование новых функций проекта, для которого он сделал ветку. Петя, который работает в основной ветке разработки, решает сделать слияние веток (рис. 68). SVN предлагает 3 возможных сценария слияния веток (рис. 69). Для рассмотрения разницы этих сценариев положим что А это ветка-приемник, в рабочей копии которой делают слияние, В это ветка-источник с которой делают слияние. Сценарии слияния веток:

  1. Merge a range of revisions - этот сценарий работает следующим образом. SVN берет начальное и конечное состояние ветки В, вычисляет последовательные изменения в файлах этой ветки и последовательно применяет эти изменения на файлы ветки А. Если эти изменения вызовут конфликт, то его нужно будет разрешить, в противном случае произойдет слияние файлов.
  2. Reintegrate a branch - этот сценарий работает следующим образом. SVN берет текущее состояние веток А и В, вычисляет какие файлы нужно изменить для того что бы из А получить В и сравнивает эти файлы. Если в этих файлах возникает конфликт, то его нужно будет разрешить, в противном случае произойдет слияние файлов.
  3. Merge two different trees - самый простой и в то же время опасный сценарий слияния. Данный вид слияния работает следующим образом. SVN берет текущее состояние веток А и В, вычисляет какие файлы нужно изменить для того что бы из А получить В, делает эту замену в рабочей копии через механизм Delete/Copy. В этом случае не возникает никаких конфликтов, но если в А были какие либо изменения то они пропадут.

В нашем случае Петя выбирает второй вариант сценария и указывает делать слияние с веткой demo_branch (рис. 70). Результат работы команды Merge (рис. 71). Естественно при слиянии возникли конфликты, которые нужно разрешить (рис. 72).
После разрешения конфликтов Петя фиксирует изменения в репозитории и обязательно комментирует свои действия (рис. 73). Как разрешаются конфликты в SVN мы рассматривали в разделе работы с рабочей копией. Всё, слияние ветки demo_branch с основной веткой разработки выполнено.

 Рис. 67. Состояние рабочих копий веток Пети и Васи перед слиянием веток
Рис. 67. Состояние рабочих копий веток Пети и Васи перед слиянием веток

Рис. 68. Слияние веток в рабочей копии Пети
Рис. 68. Слияние веток в рабочей копии Пети

Рис. 69. Диалоговое окно выбора сценариев слияния веток
Рис. 69. Диалоговое окно выбора сценариев слияния веток

Рис. 70. Диалоговое окно выбора ветки источника для слияния
Рис. 70. Диалоговое окно выбора ветки источника для слияния

Рис. 71. Окно протокола слияния веток проекта
Рис. 71. Окно протокола слияния веток проекта

Рис. 72. Состояние рабочей копии Пети после слияния веток
Рис. 72. Состояние рабочей копии Пети после слияния веток

Рис. 73. Диалоговое окно для задания комментария при фиксации результат слияния меток.
Рис. 73. Диалоговое окно для задания комментария при фиксации результат слияния меток.

Комментарии

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Syntax highlight code surrounded by the {syntaxhighlighter SPEC}...{/syntaxhighlighter} tags, where SPEC is a Syntaxhighlighter options string or "class="OPTIONS" title="the title".
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступны HTML теги: <a> <p> <span> <s> <strike> <div> <h1> <h2> <h3> <h4> <h5> <h6> <img> <map> <area> <hr> <br> <br /> <ul> <ol> <li> <dl> <dt> <dd> <table> <caption> <tbody> <tr> <td> <em> <b> <u> <i> <strong> <del> <ins> <sub> <sup> <quote> <blockquote> <pre> <address> <code> <cite> <embed> <object> <param> <strike>
  • Использовать как разделитель страниц.

Подробнее о форматировании