Открыть Электронные книги
Категории
Открыть Аудиокниги
Категории
Открыть Журналы
Категории
Открыть Документы
Категории
Распределенная
система
контроля
версий Bazaar
Дмитрий Васильев
Когда активно работаешь с файлами, будь то исходные тексты программ, файлы
конфигурации или статья, то в большинстве случаев нужно использовать какую-либо
систему контроля версий. Например, в данный момент я переписываю это введение, и так как
я использую систему контроля версий, то смогу в любой момент вернуться к одному
из предыдущих вариантов, если мне не понравится этот. Так как основная работа с файлами –
это их изменение, то наличие возможности вернуться к предыдущей версии дает огромную
уверенность, что, в свою очередь, положительно влияет на производительность. Если работа
идет в команде, то система контроля версий необходима, в противном случае в какой‑то
момент времени работа команды может застопориться.
От централизованных ное движение в эту сторону. Например, n S ubve rsion (ht tp: //subversion.
систем к распределенным из централизованных систем боль- tigris.org) – на данный момент на-
Рассмотрим, что сейчас происходит шинство могут назвать следующие: иболее популярная централизо-
в области систем контроля версий с от- n CVS (http://www.nongnu.org/cvs) – ванная система контроля вер-
крытым исходным кодом. Пока это мо- постепенно исчезающая, но все сий, изначально разработанная
жет быть не так очевидно, но просмат- еще популярная система, разрабо- как «лучший CVS» и в итоге испра-
ривается постепенный рост количест- танная поверх формата RCS фай- вившая многие ошибки в дизайне
ва распределенных систем и идет яв- лов; CVS;
70
программмирование
А что же распределенные системы? трального хранилища версий – репози- каждого изменения, чтобы избежать
Вот наиболее популярные и активно тория. В случае распределенных сис- конфликтов и ошибок. Для распреде-
развивающиеся системы: тем набор версий может быть полно- ленных систем контроля версий вет-
n Git (http://git-scm.com) – распре- стью или частично распределен между ки разработки являются одной из ос-
деленная система контроля вер- различными хранилищами, в том чис- новополагающих концепций – в боль-
сий, разработанная Линусом Тор- ле и удаленными. шинстве случаев каждая копия хра-
вальдсом. Изначально Git пред- Такая модель отлично вписывает- нилища версий является веткой раз-
назначалась для использования ся в работу распределенных команд, работки.
в процессе разработки ядра Linux, например, распределенной по все- Таким образом, механизм объеди-
но позже стала использоваться му миру команды разработчиков, ра- нения изменений с одной ветки на дру-
и во многих других проектах – та- ботающих над одним проектом с от- гую в случае распределенных систем
ких, как, например, X.org и Ruby on крытым исходным кодом. Разработ- является одним из основных, что поз-
Rails. На данный момент Git явля- чик такой команды может скачать се- воляет пользователям прикладывать
ется самой быстрой распределен- бе всю информацию по версиям и пос- меньше усилий при пользовании сис-
ной системой, использующей са- ле этого работать только на локаль- темой.
мое компактное хранилище реви- ной машине.
зий. Но в то же время для пользо- Как только будет достигнут резуль- Основные концепции
вателей, переходящих, например, тат одного из этапов работы, измене- Bazaar
с Subversion интерфейс Git может ния могут быть залиты в один из цен- Итак, начнем ближе рассматривать
показаться сложным; тральных репозиториев или опублико- Bazaar. На момент написания этой ста-
n Mercurial (http://www.selenic.com/ ваны для просмотра на сайте разра- тьи последняя версия Bazaar 1.6.
mercurial) – распределенная сис- ботчика или в почтовой рассылке. Но прежде чем рассматривать ра-
тема, написанная на языке Python Другие участники проекта, в свою боту с этой системой контроля версий,
с несколькими расширениями очередь, смогут обновить свою копию сначала обратим внимание на основ-
на C. Из использующих Mercurial хранилища версий новыми изменени- ные концепции, лежащие в ее основе.
проектов можно назвать такие, ями или попробовать опубликованные Если эти термины уже знакомы вам
как Mozilla и MoinMoin. изменения на отдельной, тестовой вет- по централизованным системам, они
n Bazaar (http://bazaar-vcs.org) – сис- ке разработки. могут иметь немного другое значение
тема, разработка которой поддер- К сожалению, без хорошей орга- в приложении к распределенной сис-
живается компанией Canonical – низации проекта отсутствие одного теме Bazaar, и их понимание важно
известной своими дистрибутивом центрального хранилища может быть для дальнейшего рассмотрения.
Ubuntu и сайтом https://launchpad.net. минусом распределенных систем. Ес- n Ревизия – это сохраненное состоя-
Система в основном написана ли в случае централизованных сис- ние файлов и директорий, включая
на языке Python и используется тем всегда есть один общий репози- их содержимое и иерархию в задан-
такими проектами, как, например, торий, откуда можно получить послед- ный момент времени. С ревизией
MySQL и Drupal. нюю версию проекта, то в случае рас- также связана мета-информация,
пределенных систем нужно организа- например:
Рассмотрим одну из наиболее гиб- ционно решить, какая из веток проек- автор изменения;
ких, на мой взгляд, распределенных та будет основной. дата изменения;
систем контроля версий – Bazaar. Почему распределенная система комментарий, связанный с из-
Одним из примеров гибкости Bazaar контроля версий может быть интерес- менением;
может служить возможность использо- на кому-то, кто уже использует цен- родительские ревизии, от кото-
вания как централизованной модели, трализованную систему – такую как рых произведена данная реви-
так и распределенной и даже смешива- Subversion? зия.
ние этих моделей контроля версий. Любая работа подразумевает при-
Даже если вы не согласны со мной нятие решений, и в большинстве слу- После создания, ревизии не ме-
по вопросу выбора конкретной сис- чаев необходимо пробовать различ- няются и могут быть идентифици-
темы, эта статья поможет вам понять ные варианты: при работе с система- рованы глобально уникальным но-
общие принципы работы распреде- ми контроля версий для рассмотрения мером ревизии (revision-id), напри-
ленных систем и затем остановить различных вариантов и работы над мер таким: «pqm@pqm.ubuntu.com-
свой выбор на одной из перечислен- большими изменениями служат вет- 20071129184101-u9506rihe4zbzyyz».
ных выше. ки разработки. Идентификаторы ревизий созда-
И хотя это естественная концепция, ются в момент фиксации (commit) из-
Зачем нужны пользоваться ею в Subversion непрос- менений или в момент импорта реви-
распределенные то. Тем более все усложняется в слу- зий из других систем. Идентификато-
системы? чае множественных последовательных ры ревизий необходимы для функцио-
Как следует из названия, одна из ос- объединений с одной ветки на другую – нирования системы, но вряд ли кто-
новных идей распределенных систем – в этом случае нужно безошибочно ука- то сможет использовать идентифика-
это отсутствие четко выделенного цен- зывать начальные и конечные версии тор такого типа в разговоре. Специ-
72
программмирование
n locations.conf – описывает конфигурационные пара- ки. Если требуется зафиксировать только отдельную ди-
метры для отдельных веток; ректорию или набор файлов, их можно указать вслед за ко-
n authentication.conf – описывает идентификационную мандой, как здесь:
информацию для доступа к удаленным серверам.
bzr commit -m "Изменения" README.txt src
Каждая ветка также может содержать файл конфигу-
рации, в этом случае он находится в каталоге .bzr/branch/ Если при создании нового проекта планируется созда-
branch.conf внутри ветки. вать несколько локальных веток, то можно воспользовать-
После того, как мы настроили свое имя и e‑mail командой ся описанным выше разделяемым репозиторием для эко-
whoami, эта информация записывается в файл bazaar.conf, номии места:
и в простейшем случае он будет выглядеть так:
$ bzr init-repo repo
$ cd repo
[DEFAULT] $ bzr init trunk
emai = John Doe <john@nowhere> $ cd trunk
Создание файлов
Работаем самостоятельно $ bzr add
Даже если вы работаете в команде, в какой-то момент $ bzr commit -m "Испортирование проекта"
времени все равно приходится работать одному, и с точки
зрения многих команд Bazaar в этом случае мало что ме- Первая команда init-repo создает в директории repo раз-
няется. деляемый репозиторий, и под директорией repo могут хра-
Если у вас уже есть готовый проект и его надо поста- нится различные ветки проекта. Основную ветку мы созда-
вить под контроль версий, нужно начать со следующей це- ем следующей командой init, которая уже была описана вы-
почки команд: ше. В случае создания разделяемого репозитория в дирек-
тории repo/.bzr хранится репозиторий и в директории repo/
$ cd project-directory trunk/.bzr ветка.
$ bzr init
$ bzr add Если при добавлении мы хотим игнорировать какие-
$ bzr commit -m "Импортирование проекта" либо объекты, можно воспользоваться командой ignore,
ее синтаксис:
Здесь первая команда init создает в рабочей директо-
рии project-directory служебную директорию .bzr, в которой bzr ignore имена объектов
хранятся репозиторий и ветка проекта.
Следующая команда, add, рекурсивно добавляет все Эта команда создаст в корневой директории ветки файл
файлы и директории в рабочем каталоге под контроль вер- .bzrignore, в котором будут записаны имена или шаблоны
сий. Если нет необходимости в рекурсивном добавлении, для игнорирования. Если удобно, то данный файл также
то можно использовать опцию --no-recurse или перечис- можно редактировать в текстовом редакторе.
лить необходимые для добавления объекты сразу вслед Глобальные правила игнорирования можно задать в кон-
за командной. фигурационном файле ignore в каталоге с конфигурацией,
Bazaar может контролировать и, соответственно, добав- ~/.bazaar/ignore для UNIX-подобных систем.
лять командой add, файлы, директории и символические Кроме задания полных имен и шаблонов, используемых
ссылки (для ссылок хранится значение ссылки, а не объ- командной оболочкой, таких как *.py[co], *.o, можно исполь-
ект, на который она ссылается). зовать регулярные выражения:
Если в процессе работы над проектом создаются новые
файлы и директории, которые нужно хранить под контро- bzr ignore "RE:lib/.*\.o"
лем версий, они также должны быть добавлены командой
add или внесены в список игнорируемых файлов, описан-
ной ниже, командой ignore. Если этого не сделать, файлы Просмотр изменений
будут показываться Bazaar как неизвестные. Когда закончен очередной этап изменений, хорошей прак-
И последняя команда, commit, фиксирует изменения тикой, прежде чем фиксировать эти изменения в системе
на ветке и в репозитории, создавая новую ревизию. Опция контроля версий, может быть их просмотр.
-m позволяет указать комментарий к ревизии прямо из ко- Команда status показывает изменения в рабочем дере-
мандной строки. Без этой опции для создания коммента- ве с момента последней ревизии:
рия будет вызван текстовый редактор.
На данный момент в Bazaar нет жесткого ограниче- $ bzr status
ния на размер комментария (единственное ограничение – modified:
это достаточно большой, максимальный размер строки README.txt
unknown:
в Python), но рекомендуется делать их разумной длины, до- db.tmp
статочной для описания сделанных изменений.
По умолчанию команда commit фиксирует все измене- Команда diff показывает изменения в текстовых фай-
ния на ветке, даже если запущена из-под директории вет- лах в стандартной унифицированной форме:
bzr diff -r 100.. При выпуске каждой версии имеет смысл помечать ее,
bzr diff -r 100..120
чтобы в будущем можно было использовать более простые
Первая команда показывает все изменения, начиная символические имена для работы с этой ревизией. Это мож-
с ревизии 100, а вторая – между ревизией 100 и 120. но сделать командой tag:
Для просмотра истории ревизий используется коман-
да log. Bazaar использует иерархическую историю, где объ- bzr tag version-1.0
единенные с данной веткой ревизии показываются с от-
ступами в виде дерева. В этом случае визуально проще После этого созданную метку можно использовать в дру-
отделить объединенные изменения от изменений на ос- гих командах следующим образом:
новной ветке:
bzr diff -r tag:version-1.0
$ bzr log
------------------------------------------------------------
revno: 100 Исправление ошибок
committer: John Doe <john@nowhere>
branch nick: trunk
К сожалению, ошибок невозможно избежать, они случают-
timestamp: Tue 2008-08-19 16:25:36 +0100 ся, и это надо принимать и быть к этому готовым. Bazaar
message: разработан таким образом, что большинство ошибок мож-
Объединены изменения с работы
но исправлять, в том числе и с использованием отдель-
------------------------------------------------------------
revno: 100.1.1 ных команд. Рассмотрим различные ситуации и их раз-
committer: John Doe <john@nowhere> решение.
branch nick: work
timestamp: Tue 2008-08-19 09:54:08 -0500 Если вы случайно поставили под контроль версий
message: не то рабочее дерево, то можно удалить служебный ката-
Добавлен файл README.txt лог .bzr, хотя стоит быть внимательным, чтобы не удалить
что-то нужное.
С командой log так же, как и с командой diff, можно ис- Если случайно под контроль версий был поставлен
пользовать опцию -r для указания необходимых ревизий файл, который нет необходимости хранить под контролем
для просмотра. версий, то его можно удалить командной remove, но без ис-
Для просмотра краткой истории изменений, не включа- пользования опций команда не будет удалять изменен-
ющей описание ревизий с объединенных веток, можно вос- ный файл:
пользоваться опцией --short:
bzr add file.txt
bzr remove file.txt
$ bzr log --short
bzr: ERROR: Can't safely remove modified or unknown files:
100 John Doe 2008-08-19 [merge]
Объединены изменения с работы
added:
file.txt
Use --keep to not delete them, or --force to delete them
Кроме того, историю ревизий можно просматривать regardless.
для отдельного файла или директории, добавив его имя
после команды: Соответственно, можно использовать опцию --keep, что-
бы оставить файл на диске, но удалить его регистрацию
bzr log README.txt или опцию --force, чтобы удалить и регистрацию, и файл.
Надо заметить, что если вы удалите файл, не используя
Команда cat выводит содержимое файла для ревизии Bazaar, то Bazaar будет считать, что необходимо удалить
заданной опцией -r: и регистрацию файла.
Команда revert возвращает все файлы и директории
$ bzr cat -r 100 README.txt в состояние на момент последней фиксации, но при этом
Файл README сохраняет измененные файлы под другими именами. Она
действует рекурсивно, и если нужно вернуть только не-
После просмотра изменений их можно зафиксировать сколько файлов, то надо быть внимательным и указывать
командой commit, которая была описана выше. в командной строке только их:
74
программмирование
bzr revert ветку в каталоге remote, и в итоге создаем еще одну копию,
копируя локальную ветку в каталог local:
Если вы случайно сделали фиксацию, то можно исполь-
зовать команду uncommit, чтобы убрать последнюю ревизию $ cd projects
$ bzr init-repo project
и вернуть рабочее дерево в состояние до момента фикса- $ cd project
ции. Эта команда позволяет также исправлять и коммен- $ bzr branch bzr+ssh://some.host/some/project remote
тарии к ревизии: Branched 10 revision(s).
Кроме того, команда uncommit позволяет отменить не- Если теперь в каталоге remote мы посмотрим инфор-
сколько последних ревизий, например, три последние: мацию о ветке командной info, то увидим ассоциирован-
ную родительскую ветку:
bzr uncommit -r -3
$ cd remote
$ bzr info
Если нет необходимости удалять ревизии, а нужно толь-
Standalone tree (format: pack-0.92)
ко вернуть рабочее дерево в прежнее состояние, то можно
Location:
использовать команду revert с опцией -r: branch root: .
Исправить неправильно поставленные метки можно Хотя возможно большое количество сценариев работы,
с помощью команды tag, например, перенести метку на дру- в нашем примере все локальные изменения будут делать-
гую ревизию можно с помощью опции --force, а удалить с по- ся на ветке в каталоге local, а ветка в каталоге remote будет
мощью опции --delete: отслеживать все изменения, сделанные на удаленной вет-
ке. Но в простейшем случае можно использовать и только
bzr tag --delete version-1.0 одну локальную ветку.
bzr tag --force version-2.0
Итак, представим, что мы проделали некоторую рабо-
ту и создали несколько ревизий на ветке local. Теперь мы
Работаем в команде обновим копию удаленной ветки изменениями, сделанны-
После того как мы рассмотрели работу с Bazaar в одино- ми другими разработчиками, и потом объединим наши из-
честве, рассмотрим распределенные возможности при ра- менения. Для обновления ветки нужно выполнить коман-
боте в команде (или по такому же сценарию вы можете ра- ду pull в каталоге remote, при этом будут скачаны и добав-
ботать из нескольких мест, например, c работы и из дома). лены все ревизии, которые были сделаны на родительской
В простейшем случае, если вы работаете в команде, кто- ветке после момента последнего обновления:
то из разработчиков уже мог создать центральную ветку
Bazaar, или при работе в паре это может быть одна из ло- bzr pull
кальных веток другого разработчика, которую вам необхо-
димо скопировать к себе. Кроме работы с файловой сис- Так как изменения на ветке local происходили парал-
темой, Bazaar может работать со следующими протокола- лельно с изменениями на удаленной ветке, то мы не мо-
ми: FTP, HTTP, HTTPS, SFTP и собственным оптимизиро- жем просто сделать pull, а должны объединить изменения
ванным протоколом bzr. Одним из простейших способов с помощью команды merge в каталоге remote:
открыть к ветке доступ для чтения может быть использо-
вание HTTP/HTTPS. В этом случае достаточно в конфигу- bzr merge ../local
рации веб-сервера открыть, с учетом необходимых огра-
ничений, директорию с веткой на доступ, как и любую дру- Если путь не указан, то merge как и pull будет использо-
гую директорию. Для доступа на запись рекомендуется ис- вать путь к родительской ветке. При объединении изменя-
пользовать соединение через SSH, которое можно устано- ется только рабочее дерево, чтобы сохранить объединен-
вить, используя схему bzr+ssh://. В этом случае автомати- ные изменения, нужно сделать фиксацию командой commit.
чески будет использоваться собственный протокол Bazaar Bazaar использует качественный алгоритм объединения,
через SSH туннель. К сожалению, на данный момент собст- учитывающий возможные прошлые объединения, и во мно-
венный протокол сам по себе не имеет никаких ограниче- гих случаях не надо заботиться о таких тонкостях, как на-
ний на доступ. чальная и конечная ревизии для объединения.
Для копирования ветки используется команда branch, В случае если в параллельных ветках было изменено
которая по умолчанию копирует все ревизии из указанно- одно и то же место в файле, автоматическое объединение
го места в локальный каталог, создавая новую ветку. В при- может не сработать, и требуется устранить конфликты вруч-
мере ниже мы создаем разделяемый репозиторий для эко- ную. При объединении бинарных файлов по умолчанию лю-
номии места и затем копируем удаленную ветку, создавая бые параллельные изменения всегда будут конфликтовать,
76