Subversion – использование нескольких веток разработки

Владимир | | Subversion.

Картинка для subversion
В этой статье я продолжу рассказ об использовании Subversion – одной из самых популярных на сегодняшний день систем контроля версий.

В этот раз речь пойдет об использовании нескольких веток разработки.

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

Допустим, вы закончили разработку первой версии web приложения (или просто сайта). Теперь нужно перенести его на сервер хостера. В большинстве случаев при этом придется изменить параметры подключения к базе данных, отключить вывод подробного описания ошибок, profiling и т.п. Скорее всего, эти изменения затронут несколько файлов.

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

Как раз в этом случае нам и пригодится возможность Subversion создавать параллельные ветки разработки.

Идея простая. Создаем ветку для серверной версии проекта. Вносим в нее необходимые изменения и «заливаем» файлы на сервер. После этого переключаемся на основную ветку (файлы с настройками возвращаются в исходное состояние) и продолжаем разработку.

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

После переноса изменений нам останется только скопировать обновленные файлы на сервер.

Теперь рассмотрим конкретный пример.

Допустим, в репозитории проекта мы создали две папки:
trunk – для основной ветки разработки;
branches – для дополнительных веток.

Примечание. О том, как это сделать можно прочитать в статье «Эффективное управление проектами (Subversion)».

На данный момент проект в рабочем состоянии и находится в папке trunk.

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

Команда

svn copy file:///path_to_project/trunk
file:///path_to_project/brunches/web
-m “Ветка для размещения проекта на сервере”

создаст новую ветку разработки, которая будет размещена в папке brunches/web репозитория.

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

Переключаемся на созданную ветку

svn switch file:///path_to_project/brunches/web

Эта команда создаст рабочую копию ветки.
Вносим в нее любые изменения (например, меняем параметры подключения к базе данных) и выполняем команду commit (т.е. сохраняем изменения в репозитории).

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

Теперь переключаемся на trunk

svn switch file:///path_to_project/trunk

И продолжаем работу.

В какой-то момент мы нашли и исправили ошибку в одном из файлов проекта. Теперь нужно исправить эту же ошибку на сервере. При этом в файл, который содержал ошибку, были внесены экспериментальные изменения, которые не должны попасть на сервер.

Т.е. нам нужно «слить» часть изменений из одной ветки в другую.

Прежде всего, нужно четко знать номера ревизий, которые содержат нужные изменения. Тут как раз и пригодятся созданные комментарии.

Посмотреть историю изменений можно с помощью команды

svn log

Она выведет список ревизий с комментариями. С помощью дополнительных параметров этой команды можно ограничить список:

svn log --stop-on-copy – выводит перечень ревизий между последней и ближайшей, в которой была выполнена операция копирования (создания ветки)
svn log -r 100:200 – список изменений между ревизиями 100 и 200
svn log -r 100:HEAD – между ревизией 100 и последней ревизией проекта.

Допустим, мы выяснили, что нужные нам изменения сделаны в ревизиях 205 и 206 основной ветки проекта.

Теперь переключаемся на ветку brunches/web

svn switch file:///path_to_project/brunches/web

И выполняем слияние

svn merge -r 205:206 file:///path_to_project/trunk

Эта команда выполнит слияние изменений из ревизий 205 и 206 ветки trunc в текущую папку (на данный момент в этой папке находится рабочая копия ветки brunches/web).

Теперь можно зафиксировать изменения ветки brunches/web в репозитории с помощью команды commit и скопировать исправленную версию приложения на сервер.

Очень важно. При выполнении команды commit обязательно в комментарии укажите номера ревизий, из которых взяты изменения (например, «изменения из trunk -r 205:206»). Это позволит избежать повторного копирования этих изменений в дальнейшем.

После этого, можно опять переключаться на основную ветку (trunk) и продолжать разработку.

Как видите, все довольно просто, а главное – удобно.

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

Заключение

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

Удачи!

  • Создание ветки для хранения изменений, зависящих от окружения (например, параметров подключения к БД), на мой взгляд неудачная практика. Я не против бранчей при деплое на боевой сервер. Но не потому, что на сервере надо вносить изменения в код!

    • В принципе, согласен. Но нужен был простой и понятный пример 🙂

      • Пример нормальный, но вот причина так делать меня покоробила. Такие действия ведут лишь к дополнительной головной боли.

  • Создание ветки для хранения изменений, зависящих от окружения (например, параметров подключения к БД), на мой взгляд неудачная практика. Я не против бранчей при деплое на боевой сервер. Но не потому, что на сервере надо вносить изменения в код!

    • В принципе, согласен. Но нужен был простой и понятный пример 🙂

      • Пример нормальный, но вот причина так делать меня покоробила. Такие действия ведут лишь к дополнительной головной боли.

  • Necromancer

    причина внесения изменений в код при разных ветках вполне реальна, например миграция между базами MySQL и Oracle (sequence и auto increment)

  • Necromancer

    причина внесения изменений в код при разных ветках вполне реальна, например миграция между базами MySQL и Oracle (sequence и auto increment)

  • Wet

    Делаем например вот так:

    switch ($_SERVER['SERVER_NAME'])
    {
    case 'project.local':
    $dbHost = 'localhost';
    break;
    case 'project.ru':
    case 'www.project.ru':
    $dbHost = 'database.project.ru';
    break;
    default:
    exit('Host not found');
    }

    И не паримся…

    • Не хочется нагружать сервер лишними проверками.

  • Wet

    Делаем например вот так:

    switch ($_SERVER['SERVER_NAME'])
    {
    case 'project.local':
    $dbHost = 'localhost';
    break;
    case 'project.ru':
    case 'www.project.ru':
    $dbHost = 'database.project.ru';
    break;
    default:
    exit('Host not found');
    }

    И не паримся…

    • Не хочется нагружать сервер лишними проверками.

  • Макс

    Насколько я понимаю в версии 1.5 уже не надо запоминать диапазон ревизий при слиянии? Просто на русском документация только по версии 1.4, а уже 1.6+ актуальная версия 🙁

    • Если я правильно понял, вы имеете ввиду Merge tracking.

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

      Но такой вариант хорош если нужно перенести ВСЕ изменения. Если нужна только часть, диапазон ревизий все же придется вспомнить 🙂 (для этого оставлена возможность слияния вручную).

  • Vladbbk

    Подскажите , а ка кже установка плагинов для wp как они попадут в svn. Ведь subversion сама не добавляет.

    • Не совсем понял вопрос. Официальный репозиторий плагинов WP использует Subversion. Вы коммитите в него также как и в любой другой репозиторий. Что именно subversion должна сама добавлять?

  • rusk

    А про svn:ignore не слышали? У меня проект работает и на локалхосте и на сервере в тестовом окрушении и на продакшн. Везде разные пути, параметры подключения итеде. Ставлю игнор на папку с конфигами и всё.

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