1   Работа в централизованном стиле

1.1   Обзор

Этот документ описывает один из возможных подходов к использованию Bazaar. А именно, использование распределенной системы контроля версий Bazaar, в централизованном стиле. Bazaar разработана, что бы быть гибкой и допускать различные подходы к работе, начиная от полностью децентрализованного, до практически централизованного. Подход описанный здесь позволяет новым пользователям проще вникнуть в более продвинутое использование Bazaar и смешивать централизованные и децентрализованные операции.

В общем случае, данный документ интересен для пользователей переходящих с централизованных систем, таких как CVS, или Subversion. В таких системах обычно есть единственный центральный сервер на котором хранится код проекта и участники команды работают над этим кодом, синхронизируя свою работу. Такой режим так же подходит для разработчика-одиночки, работающего на нескольких различных машинах.

1.2   Начальные установки

В самом начале, для более удобной работы с Bazaar, желательно осуществить достаточно простые шаги по настройке.

1.2.1   Настройка e-mail пользователя

Строка идентифицирующая пользователя сохраняется при каждой фиксации. Хотя она не обязательно должна быть аккуратной или уникальной она будет использоваться в сообщениях журнала и аннотациях, таким образом лучше что бы она была похожа на что-то реальное.

% bzr whoami "Иван Пупкин <ivan@pupkin.ru>"

1.2.2   Настройка локального репозитория

В общем случае ветки Bazaar копируют полную историю изменений вместе с собой, что, кстати, позволяет работать в полностью децентрализованном стиле. Как оптимизация для связанных веток возможно объединять их хранилища таким образом, что отпадает необходимость в копировании полной истории изменений при создании новой ветки.

Лучший способ сделать это - создать Разделяемый репозиторий. В общем случае, ветки будут разделять хранилище если они находятся в подкаталоге этого репозитория. Давайте создадим Разделяемый репозиторий в нашем домашнем каталоге и таким образом все ветки которые мы будем создавать под ним будут разделять хранилище истории.

% bzr init-repo --trees ~

1.2.3   Настройка удаленного репозитория

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

Давайте создадим разделяемое место для нашего проекта на удаленной машине и назовем его centralhost. Мы снова используем Разделяемый репозиторий для оптимизации использования дисков.

% bzr init-repo --no-trees sftp://centralhost/srv/bzr/

Можно рассматривать этот шаг как похожий на установку CVSROOT, или репозитория Subversion. Опция {{{–no-trees}}} указывает Bazaar не создавать рабочий каталог в репозитории. Нам это подходит, т.к. никто не будет напрямую что-то изменять на ветках в центральном репозитории.

1.3   Миграция рабочего проекта в Bazaar

Теперь, когда у нас есть репозиторий давайте создадим проект под контролем версий. В большинстве случаев у вас уже есть какой-то код с которым вы работаете и для хранения которого вы хотели бы использовать Bazaar. Если код изначально уже был под контролем версий существует много способов конвертировать проект в Bazaar без потери истории изменений. Но эти способы находятся вне тем рассматриваемых в данном документе. Смотрите Отслеживание изменений на основной ветке для некоторых способов (секция “Конвертирование и сохранение истории”).

1.3.1   Разработчик 1: Создание первой ревизии

Сначала нам нужно создать ветку в нашем удаленном репозитории, там где мы хотели бы хранить наш проект. Допустим, что у нас уже есть проект “sigil”, который мы хотели бы хранить под контролем версий.

% bzr init sftp://centralhost/srv/bzr/sigil

Это можно рассматривать как ветку “HEAD” в терминах CVS, или как “trunk” в терминах Subversion. Назовем это веткой разработки dev.

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

% cd ~
% mkdir work
% cd work
% mkdir sigil
% cd sigil
% bzr checkout sftp://centralhost/srv/bzr/sigil dev
% cd dev
% cp -ar ~/sigil/* .
% bzr add
% bzr commit -m "Первый импорт Sigil"

Выше мы создали пустую ветку /sigil на centralhost и затем загрузили эту пустую ветку на нашу рабочую машину что бы добавить файлы из нашего старого проекта. Есть много способов настроить свой рабочий каталог, но шаги выше упрощают дальнейшую работу с ветками для работы над ошибками, или новыми функциями. И одна из наиболее сильных сторон Bazaar - это именно отличная работа с ветками.

На этом этапе, т.к. мы создали рабочую копию (checkout) удаленной ветки, все фиксации которые будут сделаны в ~/work/sigil/dev/ будут автоматически сохранены и локально и на centralhost.

1.3.2   Разработчик N: Получение рабочей копии проекта

Так как первый разработчик проделал всю работу по созданию проекта все остальные разработчики могут просто получить рабочую копию ветки. Хотя они все еще должны следовать разделам Настройка e-mail пользователя и Настройка локального репозитория.

Получим рабочую копию текущего дерева разработки:

% cd ~/work/sigil
% bzr checkout sftp://centralhost/srv/bzr/sigil dev

Теперь, когда два человека имею рабочую копию sftp://centralhost/srv/bzr/sigil будут ситуации когда одна из копий будет не синхронизирована с текущей версией. Во время фиксации Bazaar проинформирует пользователя об этом и не допустит фиксации. Для получения последних изменений нужно использовать bzr update. Эта команда может потребовать разрешения конфликтов если были изменены одни и те же файлы.

1.4   Разработка на отдельных ветках

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

Обычно лучше вести разработку на различных ветках и затем, как только изменения достаточно стабильны, интегрировать их обратно на основную ветку. Это одно из наибольших изменений по сравнению с работой в CVS/SVN. Обе эти системы позволяют работать с отдельными ветками, но их алгоритмы объединения достаточно слабы и поэтому с ними сложно держать все синхронизировано. Bazaar отслеживает что уже было объединено и может даже прикладывать изменения к файлам которые были переименованы.

1.4.1   Создание и работа на новой ветке

Мы бы хотели, что бы наши изменения были доступны другим даже если они пока еще не закончены. Таким образом мы создадим новую публичную ветку на centralhost и будем отслеживать ее локально.

% cd ~/work/sigil
% bzr branch sftp://centralhost/srv/bzr/sigil \
             sftp://centralhost/srv/bzr/sigil/doodle-fixes
% bzr checkout sftp://centralhost/srv/bzr/sigil/doodle-fixes doodle-fixes
% cd doodle-fixes

Теперь у нас есть место где мы можем исправлять все ошибки для doodle. И мы не будем прерывать никого кто работает над другими частями кода. Так как у нас есть рабочая копия (checkout) все фиксации которые мы делаем на ~/work/sigil/doodle-fixes/ так же появятся и на centralhost. [1] Также возможно, что бы два разработчика совместно работали над одной из этих веток, так же как они совместно работают над веткой dev. [2]

[1]Может показаться странным иметь ветку в подкаталоге другой ветки. Но это нормально, можно думать об этом как о иерархическом пространстве имен где вложенная ветка является производной от внешней ветки.
[2](1, 2)

Когда используется множество независимых веток каждый раз набирать полный URL занимает много времени. Мы рассматриваем различные методы, что бы обойти это, например псевдонимы для веток и т.п. Но пока плагин bzrtools предоставляет команду bzr cbranch. Эта команда на основе базовой ветки создает новую публичную ветку и рабочую копию этой ветки всего одной командой. Конфигурирование cbranch не входит в рамки описания этого документа, но финальная команда выглядит следующим образом:

% bzr cbranch dev my-feature-branch

1.4.2   Объединение изменений обратно

Когда решено что некоторые изменения из doodle-fixes готовы для объединения на основную ветку нужно просто сделать следующее:

% cd ~/work/sigil/dev
% bzr merge ../doodle-fixes

Теперь изменения доступны на ветке dev, но они пока еще не были зафиксированы. В этот момент нужно просмотреть финальные изменения и проверить, что код компилируется и проходят все тесты. Команды bzr status и bzr diff хорошие инструменты для этого. Так же нужно разрешить возможные конфликты. Bazaar не допустит фиксации пока не будут разрешены все конфликты. В этом случае вы случайно не зафиксируете маркеры конфликта. Команда bzr status покажет конфликты и изменения, или можно использовать bzr conflicts что бы увидеть только конфликты. Используйте bzr resolve file/name, или bzr resolve --all как только конфликты были разрешены. [3] Если существуют конфликты которые особенно сложно разрешить можно использовать команду bzr remerge. Эта команда позволит использовать другие алгоритмы объединения и также позволит увидеть строки оригинального кода (--show-base).

[3]Некоторые системы позволяют разрешать конфликты как часть процесса объединения. Мы обнаружили, что обычно проще разрешать конфликты когда можно просматривать полное дерево, а не только отдельные файлы. Это дает намного больше контекста и также позволяет запускать тесты когда проблема будет решена.

1.4.3   Рекомендации по созданию веток

Один из часто используемых способов работы с набором веток - это дать каждому разработчику свою собственную ветку и собственное место для работы на центральном сервере. Это можно сделать так:

% bzr branch sftp://centralhost/srv/bzr/sigil \
             sftp://centralhost/srv/bzr/sigil/user-a
% bzr branch sftp://centralhost/srv/bzr/sigil \
             sftp://centralhost/srv/bzr/sigil/user-b

Это дает каждому разработчику собственную ветку для работы. И они смогут легко создать новые ветки с помощью [2]

% bzr branch sftp://centralhost/srv/bzr/sigil/user-a \
             sftp://centralhost/srv/bzr/sigil/user-a/feature
% cd ~/work/sigil
% bzr checkout sftp://centralhost/srv/bzr/sigil/user-a/feature myfeature

1.5   Глоссарий

1.5.1   Разделяемый репозиторий

Bazaar поддерживает концепцию “Разделяемый репозиторий”. Эта концепция похожа на традиционные концепции репозиториев в других системах контроля версий, таких как CVS, или Subversion. Например, в Subversion у вас есть удаленный репозиторий, где хранится вся история и локально история не хранится, а хранится только рабочая копия файлов. Конечно “Разделяемый” в данном контексте значит, что он разделен между ветками. Он может быть разделен между людьми, но отдельные ветки также могут быть разделены между людьми.

В Bazaar термин “Разделяемый репозиторий” - это место где несколько веток могут разделять их историю ревизий. Что бы поддерживать децентрализованную схему работы каждая ветка может хранить свою собственную историю ревизий. Но часто это не эффективно, т.к. зависимые ветки разделяют историю и они могут так же разделять и хранилище истории.