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

.. sectnum::


Обзор
=====

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

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

.. _Bazaar: http://bazaar.canonical.com

.. contents::
        Содержание


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

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


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

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

::

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


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

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

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

::

  % bzr init-repo --trees ~


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

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

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

::

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

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


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

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

.. _Отслеживание изменений на основной ветке: http://wiki.bazaar.canonical.com/TrackingUpstream

..
   TODO: На самом деле нам нужен другой документ для описания
   конвертирования проекта. Но пока ссылка выше - это лучшее.


Разработчик 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``.


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

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

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

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

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


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

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

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


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

Мы бы хотели, что бы наши изменения были доступны другим даже если они
пока еще не закончены. Таким образом мы создадим новую публичную ветку на
``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``.
[#nestedbranches]_ Также возможно, что бы два разработчика совместно
работали над одной из этих веток, так же как они совместно работают над
веткой ``dev``. [#cbranch]_

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

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

   ::

   % bzr cbranch dev my-feature-branch

.. _bzrtools: http://wiki.bazaar.canonical.com/BzrTools


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

Когда решено что некоторые изменения из ``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`` как
только конфликты были разрешены. [#resolve]_ Если существуют конфликты
которые особенно сложно разрешить можно использовать команду ``bzr
remerge``. Эта команда позволит использовать другие алгоритмы объединения
и также позволит увидеть строки оригинального кода (``--show-base``).

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


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

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

  % 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

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

  % 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


Глоссарий
=========

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

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

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


..
   vim: tw=74 ft=rst spell spelllang=en_us
