Я давно знал, что пользоваться системой контроля версий — правильно и полезно. Но все было как-то неохота. Ну вы в курсе, как это бывает. И вот, некоторое время назад, лень удалось побороть. Выбор был сделан в пользу subversion , несмотря на преимущества альтернативных систем. Видимо, чтобы по-настоящему понять преимущества Git/Darcs/Bazaar/Mercurial, нужно какое-то время поработать с SVN. А иначе — с чем сравнивать? К тому же, subversion кажется наиболее «каноничной» системой контроля версий.

1. Настройка subversion и создание первого хранилища

По старой доброй традиции я использовал сервер под управлением FreeBSD 🙂 Устанавливаем subversion:

pkg_add -r subversion

Создаем пользователя svn с группой svn и nologin в качестве оболочки, затем создаем каталог, где будут лежать все репозитории:

adduser
# …
mkdir / home / svn / repos
chown -R svn:svn / home / svn

Прописываем в /etc/rc.conf:

svnserve_enable=»YES»

… и запускаем svnserve:

/ usr / local / etc / rc.d / svnserve start

Ура, subversion настроен и запущен! Теперь нужно создать первый репозиторий :

svnadmin create / home / svn / repos / test
cd / home / svn / repos / test / conf
vim svnserve.conf

В svnserve.conf пишем следующее:

[general]
# анонимные пользователи не имеют доступа к репозиторию
# если хотим раздавать исходники всем подряд, меняем на read
anon-access = none
# зайдя по логину-паролю, получаем права на чтение и запись
auth-access = write
# логины и пароли хранятся в файле ./passwd
password-db = passwd
# название репозитория
realm = Test project

Также требуется создать в каталоге conf файл passwd:

[users]
eax = superpuperparol

И — финальный аккорд:

chown -R svn:svn / home / svn

Теперь проверяем все это дело — на этой же машине или на другой:

svn co svn: // example.ru / test
cd test

Создаем файл test.pl, пишем в него что-нибудь, затем заливаем в хранилище:

svn add test.pl
svn ci

Оказалось, пользоваться SVN совсем не сложно!

Давайте попробуем еще одну фишку . Наверняка вам часто попадались исходники, содержащие строчку вроде этой:

# $Id: test.pl 10 2011-04-09 09:48:32Z eax $

Если вы хотите, чтобы в вашем коде также содержались имя файла (test.pl), номер ревизии (10), дата-время последнего изменения (2011-04-09 09:48:32Z) и имя пользователя, вносившего последние изменения (eax), просто допишите в комментариях:

$Id:$

… и выполните команду:

svn -R propset svn:keywords Id . / test

Вся информация будет добавляться в исходники автоматически. Как альтернативный вариант, можно прописать в ~/.subversion/config следующее:

[miscellany]
enable-auto-props = yes
[auto-props]
*.pl = svn_keywords=Id
*.pm = svn_keywords=Id

Тогда не придется вводить команды вручную.

2. Чего не хватает для комфортной работы?

Ничего не имею против VIM , но время от времени я отдаю свое предпочтение Geany . Под Виндой, к примеру, мне удобнее пользоваться им, чем каким-нибудь gvim.exe. Для работы с системами контроля версий в Geany используется плагин GeanyVC . Во FreeBSD можно поставить GeanyVC из портов (в пакеджах его почему-то нет):

portmaster -wd devel / geany-plugins

Активируем плагин в «Инструменты → Менеджер модулей», после чего станут доступны дополнительные пункты меню:

Плагин GeanyVC

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

Инсталлятор для Windows можно скачать отсюда . Только обязательно выберите плагины для вашей версии Geany. Например, плагины для Geany 0.19 могут не заработать с Geany 0.20. Также для работы GeanyVC требуется Win32Svn .

Под Windows есть множество других средств для работы с Subversion, среди которых я бы отметил TortoiseSVN и RapidSVN . Главная фишка TortoiseSVN в том, что он встраивается в контекстное меню explorer.exe. RapidSVN менее удобен, зато является кроссплатформенным (написан на C++ с использованием wxWidgets ) и имеет portable версию .

Если вы работаете в системе без прав администратора, то не сможете поставить TortoiseSVN. Кроме того, у меня с ним был странный баг. При слиянии одной из веток проекта с trunk, я получал сообщение «TortoiseSVN: neither the reintegrate source nor target can be the root of the repository», хотя под UNIX обычная команда:

svn merge svn: // example.ru / my_project / branches / some_branch

… выполнялась без каких-либо проблем.

3. Subversion и безопасность

К сожалению, svnserve не умеет шифровать трафик. Если вы трудитесь над open source проектом или работаете в интра нете (возможно, через VPN), то это и не представляет большой проблемы. Для аутентификации svnserve использует CRAM-MD5 , так что пароли перехватить не удастся. Кроме того, вы можете ограничить доступ к репозиторию с помощью фаервола (порт 3690), что обеспечит неплохой уровень безопасности. Правда, все еще остается возможной атака с помощью IP/DNS спуфинга.

Если же шифрование трафика необходимо, subversion предлагает два возможных решения — использовать Apache + mod_dav_svn + SSL или связку SVN + SSH. Сравнение этих решений приведено здесь . Если вас интересует решение на базе Apache, ознакомьтесь с этой статьей . Ниже речь пойдет о настройке SVN + SSH.

Во-первых, svnserve можно прибить, а также удалить svnserve_enable из /etc/rc.conf. Во-вторых, очевидно, нужно запустить sshd (чисто на случай, если вы работаете через telnet :). Затем создаем на сервере учетные записи разработчиков и объединить их в одну группу:

pw usermod eax -G svn

Создаем где-нибудь каталог, куда смогут писать все разработчики:

cd / mnt / projects
mkdir new_project
chown svn:svn new_project
chmod g+rwx new_project

Новое хранилище готово! Никакие дополнительные команды и conf-файлы не нужны. Check-out делается следующей командой:

svn co svn +ssh: // eax @ example.ru / mnt / projects / new_project

Обратите внимание, что на этот раз нужно задать полный путь к репозиторию. Нас попросят ввести пароль — тот самый, что установлен у пользователя на сервере. Если пароль просят ввести дважды — это нормально, просто используется две ssh-сессии. Во время check-in и update пароль будет запрашиваться только один раз. Чтобы не вводить пароли вовсе, можно воспользоваться identity file .

TortoiseSVN умеет работать с svn+ssh:// . Нужен ли ему для этого PuTTy или WinSCP — не знаю, у меня эти утилиты были до установки TortoiseSVN.

В GeanyVC для работы с svn+ssh:// требуется совершить следующую последовательность шагов. Сначала с помощью puttygen.exe создаем пару ключей. Закрытый ключ сохраняем где-нибудь на диске в незашифрованном виде, а открытый ключ дописываем на сервере в ~/.ssh/authorized_keys. Затем в PuTTy сохраняем параметры подключения к svn-серверу, указав в настройках имя пользователя и путь к только что созданному закрытому ключу. Проверяем, удается ли зайти на сервер без ввода пароля. Далее в файле «%APPDATA%/Subversion/config» находим секцию [tunnels] и пишем в ней:

ssh = $SVN_SSH «C:/Program Files (x86)/PuTTY/plink.exe»

Пробуем сделать check-out в cmd.exe:

svn co svn +ssh: // PUTTY_SESSION_NAME / mnt / projects / new_project

Правим код в Geany, пробуем сделать commit. Кстати, утверждается , что подобная последовательность действий работает и для RapidSVN.

4. Настраиваем ночные сборки

Ночные сборки обладают массой полезных свойств и реализуются довольно просто. Вот пример скрипта, который делает check-out проекта, прогоняет тесты и, в случае обнаружения ошибок, высылает отчет на заданный e-mail :

#!/usr/bin/perl

# mojo-test.pl script v 0.1
# (c) Alexandr A Alexeev 2011 | http://remontka.com/

use strict ;

## config ##
my $svn_user = ‘eax’ ;
my $svn_host = ‘example.ru’ ;
my $project_name = ‘new_project’ ;
my $project_path = ‘ mnt/projects’ ;
my $report_email = ‘eax@example.ru’ ;
#############

# делаем check-out проекта (не забыть про identity file!)
my $cmd = «svn co svn+ssh://$svn_user@» .
«$svn_host/$project_path/$project_name/ ./project» ;
`$cmd` ;
if ( $? ) {
$cmd = «echo » | » .
«mail -s ‘Failed to check-out $project_name! Error: $?'» .
» $report_email» ;
`$cmd` ;
exit 1 ;
}

# прогоняем тесты
`perl ./project/script/$project_name test > ./t.txt` ;
if ( $? ) {
`cat t.txt | mail -s ‘Test of $project_name’ $report_email` ;
}

# подчищаем за собой
`rm -rf ./project/ && rm ./t.txt` ;

Только не забудьте про crontab и identity file. Предполагается, что проект разрабатывается на базе Mojolicious , но, очевидно, аналогичный скрипт несложно написать и для проекта на C++, в котором используется CppUnit.

5. Что мы получаем в итоге?

А получаем мы следующее:

  • Весь код автоматически бэкапится на сервере. Плюс несложно настроить резервное копирование с svn-сервера еще куда-нибудь;
  • Мы всегда можем вернуться к одной из предыдущих версий (ревизий) любого файла. Вам приходилось когда-нибудь комментировать куски кода на случай, если вдруг сделанные вами изменения окажутся неверными? Так вот, больше так делать не нужно;
  • Удобная работа в команде, вплоть до одновременного редактирования одного файла несколькими людьми. Даже если вы — единственный программист в команде, как минимум, теперь вы можете переложить какую-нибудь верстку на другого человека;
  • Шифрование трафика;
  • Проще настроить ночные сборки;

Ну вот, кажется, и все, что я хотел рассказать. Как обычно, любые комментарии и вопросы приветствуются.

Дополнение: В продолжение темы — Краткая шпаргалка по основным командам Subversion и Моя шпаргалка по работе с Git .

EnglishRussianUkrainian