LXF70:Subversion1
|
|
|
Содержание |
Subversion. Установка репозитария
Часть 1: Subversion (англ. «ниспровержение», «подрыв») – это отличное решение open-source для управления процессом разработки вашего проекта. Соответственно, в LXF всегда под рукой собственный «подрывник», Грэм Моррисон, который расскажет вам об этом.
В старые добрые времена программисты имели обыкновение скрываться в своих лабораториях, записывая ленты на машинах размером с орган Кавайе-Колля, что установлен в соборе Сердца Христова в Париже. Результаты их работы, вместе с программами, которые эти результаты генерировали, можно было сохранять только на бумажных лентах, что делало совместную работу несколько затруднительной. Тим Бернерс-Ли (Tim Berners-Lee) разом изменил это. Теперь компьютеры объединены в сети, и в разрабатываемые проекты вовлекаются сотни или даже тысячи людей, активно поддерживающих друг друга. Без такого сетевого сотрудничества у нас не было бы Linux.
Магической основой совместной разработки проекта можно назвать контроль версий. При этом используется программа для отслеживания каждого единичного изменения или исправления в проекте – это сложнее сделать, чем сказать. Как вы поступите, если сразу несколько разработчиков будут редактировать один и тот же участок кода? Или если очередное дополнение тем или иным образом повредит проекту? Первому приложению контроля версий, Revision Control System, или RCS, написанному Вальтером Тичи (Walter Tichy), были присущи многие эти проблемы. Сегодня RCS в большинстве случаев заменено другими программами, среди которых присутствует пакет Subversion, о котором и пойдет речь.
Я буду исследовать Subversion в серии из трех уроков. В этом выпуске вы получите представление об администрировании сервера, от импорта проектов разработки до предоставления удаленного доступа и интеграции с сервером Apache. В следующем месяце мы охватим клиентскую часть Subversion, и третий урок покажет вам более «продвинутые» особенности, такие как ветвления (branching) и теггинг (tagging). Я очень надеюсь, что это улучшит совместную работу, но не в том смысле, что мы обсудим печать ваших собственных копий Манифеста Коммунистической партии для последующего распространения среди друзей и коллег.
Наследие CVS
Сперва – немного истории, которая объяснит, как мы получили Subversion из RCS. Хотя первоначально RCS была очень полезна, в ней имелись довольно большие «дыры». В частности, она не позволяла оперировать с проектом в целом, только с отдельными файлами, и лишь один пользователь мог работать с файлом в данное время. Дик Гран (Dick Grune), расстроенный тем, что не может использовать RCS для совместной работы со студентами над проектом компилятора, занялся разработкой альтернативы, и в 1986-м году свет увидела первая версия программы Concurrent Version System (CVS).
В основу CVS положена весьма простая идея. Дерево исходного кода проекта сохраняется на сервере, называемом «репозитарий». Каждый разработчик должен извлечь собственную копию этого дерева, скачав исходный код на свою локальную машину. Эта копия становится «рабочей». Любые изменения, которые разработчик выполняет в своей рабочей копии, должны быть занесены назад в репозитарий и зафиксированы. Если более чем один разработчик изменял одну и ту же часть кода, возникает конфликт, который CVS не в состоянии разрешить, и код требует ручного редактирования перед тем, как сервер позволит выполнить его фиксацию (commit).
Как вы могли заметить, CVS использует клиент-серверную модель. Сервер обрабатывает содержимое, когда клиент сообщает изменения, которые должны быть сделаны в дереве документов сервера. CVS не всегда используется для исходных текстов приложений: на самом деле, есть несколько странных людей, которые пытаются использовать CVS для управления всей своей жизнью, но это уже совсем другая история.
CVS – это, по сути, многодокументное расширение к RCS, и оно унаследовало некоторые проблемы, связанные с его родителем, и даже добавило немного своих собственных. В этом смысле у Subversion есть все шансы отличиться.
Новое решение
Система Subversion была разработана как непосредственная открытая замена для CVS, выстроенная «с нуля», чтобы решить многие проблемы своей предшественницы. Версия 1.01 была выпущена в марте 2004-го года, а как раз сейчас начинается тестирование версии 1.2.0 Во главе списка ее отличительных особенностей – контроль версий каталогов, который не может обеспечить CVS. Это ключевой момент, поскольку Subversion позволяет вам манипулировать каталогами таким же образом, как и файлами – переносить, переименовывать, копировать и удалять. Основанная на файлах структура CVS – причина ее еще одной большой проблемы. При фиксации изменений существует вероятность потерять соединение на полпути. В случае с CVS, результатом этого станет ситуация, когда половина файлов от разработчика будет обновлена, в то время как другая половина – нет, что не оставит администратору никакой возможности разобраться, какие файлы изменялись, а какие остались старыми. Решение, которое предлагает Subversion, заключается в том, что все изменения в репозитарии выполняются «атомарно». Это означает, что все изменения вносятся как единая транзакция, исключающая «полуобновление» файлов и двойную фиксацию. Это, наряду с другими существенными добавлениями («дешевые» ветвления и тэггинг, отличная поддержка двоичных форматов), сделает обновление до Subversion почти обязательным для пользователей CVS уже в ближайшем будущем.
Subversion доступна для загрузки с сайта http://Subversion.tigris.org под лицензией CollabNet/Tigris.org, которая аналогична лицензии Apache; ее разработчики рекомендуют версию 1.1.4. Как только вы установите эту программу, вам захочется задействовать ее для использования в своем собственном проекте.
Часть 1. Установка репозитария
Первый шаг при администрировании репозитария Subversion – создание структуры и заполнение ее файлами. Subversion использует базу данных Berkeley, которая ограничивает инсталляцию локальной файловой системой потому, что Berkeley полагается на файловую систему, которая поддерживает относительно «продвинутые» особенности, не доступные в настоящий момент в сетевых аналогах (таких как Samba или NFS). Как только будет выбрано место для размещения репозитария, вы можете создать его, используя команду svnadmin, предназначенную для внесения значительных изменений в репозитарий.
Чтобы создать собственный репозитарий с именем subres, выполните следующую команду в каталоге, в котором вы хотите разместить его (я буду использовать /usr/share):
$ svnadmin create subres
Управление репозитарием Subversion не очень отличается от CVS. Самое главное для администратора - это понять файловую систему, используемую в Subversion. Имеется в виду не файловая система типа ext3 или Reiser, а структура и организация файлов, которую ожидает получить SVN. Приведенная выше команда генерирует структуру в каталоге subres, который теперь должен содержать пару файлов и несколько директорий.
Этими директориями являются: conf, dav, db, hooks и locks. Conf содержит специфический файл конфигурации репозитария – svnserver.conf. Каталог dav содержит системную «бухгалтерскую» информацию, особым образом используемую модулями доступа Apache. Директория db хранит все системные файлы базы данных Berkeley. «Ловушки» (hooks) – это скрипты, которые могут выполняться при возникновении некоторого события (см. врезку «Ловушки Subversion»). Таким событием может являться, например, фиксация или изменение версии, и каталог hooks содержит скрипт-пример для каждой операции, которую осуществляет SVN. Директория locks содержит данные блокировок, ответственные за отслеживание доступа к репозитарию.
Для начала теории достаточно. Прежде чем приступить к использованию репозитария, нам нужно импортировать в него дерево исходного кода. Как и в случае с CVS, это можно сделать, используя команду svn import. Subversion использует URL, чтобы ссылаться на размещение, причем локальные директории предваряются тремя прямыми слэшами, чтобы показать, что это не Интернет-адрес. Позже, когда мы будем настраивать модули Apache, мы будем использовать HTTP, чтобы вернуться к более знакомому использованию прямых слэшей.
$ svn import -m "Initial project import" Adding helloworld/helloworld.cpp Adding helloworld/Makefile Committed revision 1.
Как вы видите на выводе, команда import берет содержимое каталога helloworld и помещает в репозитарий два файла; вложенные каталоги также будут включены. То, что вы видите, - концептуальное отличие Subversion от CVS: номер ревизии используется для всего обновления, а не для каждого файла. Зафиксированный номер ревизии отражает каждое атомарное обновление.
Чтобы убедиться, что файлы успешно добавлены в репозитарий, вы можете вывести список содержимого, используя команду ls:
$ svn ls file:///usr/share/subres Makefile helloworld.cpp
Чтобы извлечь рабочую копию проекта, используется команда «co» в каталоге, в который вы хотите поместить проект:
$ svn co file:///usr/share/subres A subres/helloworld.cpp A subres/Makefile Checked out revision 1
Все очень просто! И на этом мы завершим первую часть.
"Ловушки" Subversion (врезка)
«Ловушки» выполняются при наступлении определенного события в репозитарии. Каждое событие соответствует одному из следующих сценариев из каталога hooks:
Start-commit. Он запускается перед началом транзакции и проверяет, обладает ли пользователь соответствующими полномочиями для ее фиксации.
Pre-commit. Этот скрипт выполняется после завершения транзакции в репозитарии, но, что важно, до того как будет выполнена окончательная фиксация. Он нужен, чтобы убедиться, что вся транзакция придерживается политики фиксации в репозитарии. Эта политика может быть достаточно простой, например, проверка места назначения, но скрипт может также быть полезен для запросов авторизации или для занесения результата фиксации в инструмент отслеживания ошибок.
Post-commit. Этот сценарий часто используется, чтобы предоставлять информацию о новой ревизии в список рассылки, посвященный разработке проекта, после того как транзакция будет зафиксирована. Subversion даже включает пример как раз для этих целей (см. Subversiontools/hook-scripts/commit-email.pl).
Pre-revprop-change. Свойства собственной ревизии Subversion являются единственными данными в репозитарии Subversion, версии которых не отслеживаются. Это означает, что изменения этих свойств будут потеряны, если администратор не предпримет никаких действий по сохранению предыдущих значений. Именно для этого предназначен данный скрипт - он выполняется перед изменением свойств, позволяя легко автоматизировать необходимые операции.
Post-revprop-change. В зависимости от наличия сценария pre-revprop-change, этот скрипт выполняется после того, как свойства ревизии будут изменены. И снова напомню, что пакет Subversion включает пример, показывающий, как сообщить команде разработчиков о произошедших изменениях свойств.
Часть 2. Миграция с CVS
Единственной проблемой при таком импортировании проекта является то, что вы потеряете всю историю изменений, накопленную в вашей текущей системе контроля версий. К счастью, есть способ перенести вашу историю изменений в новый репозитарий Subversion.
Простейший путь сохранить историю вашего проекта – экспорт каждого значимого релиза из вашей старой системы в Subversion. Сначала вы импортируете самую раннюю версию проекта, которую содержит ваша нынешняя система контроля версий, после чего вам следует извлечь рабочую копию. Для каждого релиза, который вы хотите экспортировать в Subversion, вам нужно скопировать файлы в вашу рабочую копию, удалить все необходимые файлы и каталоги, и обновить каждую версию.
Менять файлы и каталоги в вашей рабочей копии достаточно просто, если придерживаться следующей процедуры добавления: сперва в репозитарий, затем – обновление и фиксация изменений. Стоит учесть, что Subversion обрабатывает файлы не так, как CVS: когда вы используете в Subversion команды rename и copy, будет сохраняться история переименований и копирования файлов.
Общие операции работы с файлами, для которых есть эквивалент в Subversion, - copy, rename и move, и они используются, в общем-то, таким же образом, как их аналоги в командной строке:
$ svn cp helloworld.cpp welcome.cpp A welcome.cpp $ svn rm helloworld.cpp D helloworld.cpp
Наиболее важная команда в Subversion для всех файловых операций и, вероятно, вообще для использования Subversion, это команда status. Вы можете проверить статус всех файлов в репозитарии (это особенно полезно перед фиксацией изменений), используя флаг verbose для подробного вывода:
$ svn status –v 3 3 graham . D 4 4 graham helloworld.cpp A+ - ? ? welcome.cpp 3 1 graham Makefile
Приведенный пример показывает текущее состояние файлов, содержащихся в рабочей копии. Буквы D и A в первом столбце показывают, что helloworld.cpp был удален (D), в то время как welcome.cpp был добавлен (A). Символ «+» указывает, что добавление файла welcome.cpp включает историю изменений для этого файла. Это результат использования команды copy, в отличие от ручного копирования. Числа указывают рабочую ревизию и последнюю зафиксированную версию. Первое число – текущая ревизия, а второе – последняя зафиксированная ревизия, за которой указывается автор фиксации.
Фиксация изменений и проверка статуса репозиратия должны сгенерировать вывод, подобный приведенному ниже:
$ svn commit –m "Copied and removed cpp files" Deleting helloworld.cpp Adding welcome.cpp Committed revision 6. $ svn status –v 3 3 graham . 6 graham welcome.cpp 3 1 graham Makefile
Используя приведенные выше команды, можно выстроить достойную историю изменений из истории релизов проекта. Правда, это потребует много работы, и было бы намного проще, если бы процесс был несколько автоматизирован, или хотя бы имелся инструмент для конвертирования истории изменений из других систем контроля версий. К счастью, существует пара сценариев, которые были разработаны для переноса вашего старого репозитария в репозитарий Subversion.
В вопрос миграции с CVS на Subversion разработчики внесли большой вклад – cvs2svn, сценарий Python, в частности, показывает хорошие результаты, когда выполняет перенос старых файлов из репозитария. Процесс, в первую очередь, «вынюхивает» в системе CVS все данные, касающиеся управления ревизиями, которые затем извлекаются и используются для перестроения истории изменений в Subversion. Есть несколько возможных уровней сложности для конвертирующего сценария, которые распространяются не только на само конвертирование, но также и на производительность/объем вашего репозитария.
Наиболее часто используемая опция включает только главную ветвь (так называемый trunk) репозитария CVS, (cvs2svn --trunk-only), игнорируя все исторические данные в любых ветвях и тэгах, какие у вас могут быть. Если такое использование кажется слишком ограниченным, вы можете установить только ветви и тэги, которые наиболее важны для вашего проекта (например, вы могли бы без последствий проигнорировать ночные сборки). Это выполняется с помощью флага --exclude, определяющем, какие ветви и тэги следует игнорировать. Наконец, вы можете просто импортировать залпом все сразу, и использовать скрипт cvs2svn для конвертирования репозитария в Subversion полностью.
Часть 3. Обеспечение удалённого доступа
Очевидно, что пользователи, имеющие доступ к репозитарию Subversion, могут находиться в разных частях света, и поэтому требует- ся возможность работы в сети. Это особенно верно для открытых проектов. Subversion использует Apache и особый протокол WebDAV, чтобы обеспечить доступ к репозитарию для сетевых клиентов. Установка и настройка достаточно проста, с единственным требованием, что нужен работающий Apache версии 2.0 или выше.
В этом случае установка будет состоять в простом добавлении нескольких строк в исходный файл конфигурации Apache. Нужны два модуля – mod_dav и mod_dav_svn, которые менеджер пакетов должен был добавить автоматически. Тем не менее, вам следует убедиться, что эти модули подгружаются. В файл httpd.conf нужно включить особую информацию о настройках Subversion:
<Location /svn> DAV svn SVNPath /usr/share/subres SVNAutoversioning on AuthName "LXF Subversion Repository" AuthTypeBasic </Location>
Опция DAV просто информирует Apache, какой модуль используется (svn), а SVN Path указывает на репозитарий. Поскольку Subversion использует web-сервер, поддерживающий WebDAV, то существует возможность использовать другие совместимые с DAV клиенты для доступа к репозитарию Subversion. Теоретически, такие клиенты могут рассматривать репозитарий как разновидность файловых систем, так же как мы получаем доступ к объектам Samba или NFS с помощью своего файлового менеджера.
Пока что осуществление этого требует значительных усилий, если нужно добиться истинной совместимости. Функция SVN autoversioning – это компромисс, разрешающий делать обновления с основных клиентов, без записей в журналах или комментариев, добавляемых Subversion автоматически в общем виде. Это далеко от идеала, но предоставляет дополнительную возможность выбора.
Последняя строка в нашем примере задает тип аутентификации, в настоящее время используется базовая аутентификация протокола HTTP. Доступ на запись может контролироваться путем ограничения HTTP командами, на которые Subversion может положиться как на обеспечивающие только возможность чтения:
<LimitExcept GET PROPFIND OPTIONS REPORT>
Используя этот пример, вы разрешите пользователям доступ на запись только через выделение отдельных учетных записей и соответствующий файл .htpasswd, как это было бы при нормальной конфигурации Apache. Безопасные соединения также возможны при помощи доступа к репозитарию через HTTPS вместо HTTP, и в этом случае приходится полагаться на предварительно настроенный модуль mod_ssl. После того как Apache будет настроен, вы должны получить возможность управлять репозитарием удаленно, используя URL своего сервера, вместо прежнего указателя на файлы:
$ svn co http://localhost/subres
Subversion против CVS (врезка)
Не секрет, что Subversion была разработана, чтобы заменить CVS, и поэтому работа с обоими приложениями очень похожа. С точки зрения клиента многие команды идентичны, и вы можете зачастую просто заменить cvs на svn в командной строке. Обработка происходит в фоновом режиме, и серверные и сетевые протоколы, которые имеют различия, остаются, по большей части, скрыты от конечного пользователя. Здесь приводится список некоторых команд, которые слегка отличаются:
CVS | Subversion | Функция |
cvsadmin | svnadmin | Оболочка к административным функциям |
cvsannotate | svn blame | Выводит информацию о ревизиях для файлов |
cvsco –j | svn merge | Объединяет два источника в рабочую копию |
cvshistory | svn log | Выводит журнальные сообщения |
cvsinit | svnadmin create | Создает новый репозитарий |
cvsrdiff | svn diff | Составляет список отличий для патча |
cvsremove | svn delete | Удаляет объект из репозитария |
cvsrtag | svn copy | Копирует объект, включая историю его ревизий |
Часть 4. Поддержка
Раз репозитарий запущен, вам понадобится несколько команд для поддержания его в рабочем состоянии. Наиболее важная из них – svnadmin, команда, в общих чертах аналогичная cvs admin, которая предоставляет несколько жизненно важных подкоманд. Мы уже встречались с svnadmin create, которая отвечала за генерацию репозитария. Вы можете воспользоваться командой svnadmin dump как частью процесса резервного копирования, но она полезнее для переноса содержимого между репозитариями. Команда копирует содержимое репозитария в стандартный поток вывода, используя переносимый формат dump-файла. Команда dump также позволяет вам определять диапазон ревизий репозитария, которые должны быть включены в вывод, вместо того чтобы выводить все сразу, как это происходит по умолчанию.
$ svnadmin dump /usr/share/subres > dump.txt
Партнер команды dump – svnadmin load, которая может импортировать вывод в формате dump. Однако, чтобы создать резервную копию репозитария, вам нужна другая команда – hotcopy. Благодаря базе данных Berkley, становится возможным копировать содержимое репозитария без его остановки. Стандартная инсталляция Subversion также предоставляет сценарий на Python в каталоге tools/backup, который вы можете использовать для автоматического исполнения (например, как задание cron), вместо ручного запуска svnadmin hotcopy.
Лучший способ проверить статус работающего репозитария – использование команды svnlook. Svnlook проверяет самую свежую версию, и по умолчанию имеет доступ только для чтения, так что можно не беспокоиться, что будут сделаны какие-то катастрофические изменения. Каждая команда с svnlook может быть применена как ко всему репозитарию, так и к определенной ревизии.
$ svnlook info /usr/share/subres --revision 1 graham 2005-04-15 16:33:44 _0100 (Fri, 15 Apr 2005) 22 Initial project import
Svnlook info – мощная команда, позволяющая получить общий обзор репозитария. Приведенный пример показывает автора, дату, комментарий и размер первой ревизии, сделанной в репозитарии. Каждое поле может быть получено независимо, если заменить info на author, date или log, так что команда может быть использована при разработке скриптов для использования в качестве «ловушек», упомянутых ранее.
На данный момент вы должны понимать основы работы сервера Subversion. Следующим этапом должен быть либо старт проекта в Subversion, либо спасение CVS-проекта, увядающего на вашем диске. Поскольку ваш репозитарий поднят и настроен, следующий шаг для вас и ваших коллег по разработке – использовать его, но об этом мы поговорим в следующий раз!
Подсказка (врезка)
Документация по Subversion
Лучший способ понять Subversion – это воспользоваться ее замечательной встроенной документацией. Чтобы добраться до нее, выполните svn help в командной строке. В результате вы получите список внутренних команд Subversion, по которым вы можете получить дополнительную информацию, указав имя в конце команды help, например, так:
$ svn help co
Также в сети имеется книга издательства O'Reilly, озаглавленная «Version Control with Subversion» (Контроль версий с помощью Subversion), которую можно скачать в формате PDF или HTML с сайта http://svnbook.redbean.com.