Показаны сообщения с ярлыком общее. Показать все сообщения
Показаны сообщения с ярлыком общее. Показать все сообщения

среда, 28 марта 2012 г.

bzr 2.5.0 и локализация интерфейса

Одним из нововведений в релизе bzr 2.5 стало добавление поддержки локализации выводимых сообщений. Я только что обновил у себя bzr из инсталлятора https://launchpad.net/bzr/2.5/2.5.0/+download/bzr-2.5.0-2-setup.exe и увидел, что русская локализация уже работает:

C:\>set LANGUAGE=ru

C:\>bzr
Bazaar 2.5.0 -- a free distributed version-control tool
http://bazaar.canonical.com/

Базовые команды:
  bzr init           превратить директорию в ветвь системы версий
  bzr branch         создать копию другой ветви

  bzr add            добавить файлы или директории к системе контроля версий
  bzr ignore         игнорировать файл или шаблон
  bzr mv             переместить или переименовать файл в системе контроля версий

  bzr status         вывести краткие изменения в рабочей копии
  bzr diff           вывести подробные различия

  bzr merge          принять изменения из другой ветви
  bzr commit         сохранить некоторые или все изменения
  bzr send           переслать изменения по электронной почте

  bzr log            показать историю изменений
  bzr check          проверить целостность

  bzr help init      подробные сведения например по команде init
  bzr help commands  вывести список всех команд
  bzr help topics    вывести список всех разделов справки

Что само по себе уже приятно.

Можно пробовать, о найденных проблемах сообщать в багтрекере bzr (или в группе ru_bzr, хотя я не участвовал в переводе). Радует, что нашлись активные добровольцы. Однако переведено далеко не всё, и вы тоже можете помочь с переводом: https://translations.launchpad.net/bzr и не только на русский, но и на другие языки, которыми вы свободно владеете.

Enjoy!

пятница, 5 августа 2011 г.

Bazaar уверенно удерживает третье место

Ни для кого ни секрет, что bzr не является самой-пресамой популярной DVCS по состоянию на 2011 год. По моим личным наблюдениям первое место уверенно держит git, я думаю не в последнюю очередь благодаря GitHub.

На блогах Microsoft опубликованы результаты опроса (через Twitter) предпочтений разработчиков Open Source проектов. Насколько эта выборка репрезентативна -- вопрос спорный. Однако она достаточно хорошо на качественном уровне показывает тенденции: git > hg > bzr.

Выбрав цифры только для тройки git/hg/bzr и беспощадно усредняя их можно прийти к такой средней температуре по больнице:
  • git ~77%
  • hg ~18%
  • bzr < 5%
Почему все еще имеет смысл использовать bzr? может спросить кто-то.

С моей точки зрения причины к этому могут быть следующие:
  • вы и ваша команда более чем удовлетворены работой bzr и у вас нет причин менять проверенного коня. (По моему личному мнению каждая система из тройки имеет свои недостатки, с которыми придется мириться)
  • Вы предпочитаете работать в централизованном стиле не теряя плюсов DVCS
  • вам нравится GUI интерфейс к bzr -- QBzr и/или Bazaar Explorer, и вы не хотите их потерять при переходе на другую систему. Я не раз и не два получал отзывы от различных людей, даже от (увы) бывших пользователей bzr о том, что QBzr очень хорош. И я с этим согласен
  • вам нравится использовать Launchpad для хостинга своих открытых проектов.
  • вы используете bzr для работы с svn через bzr-svn. Плюшки в виде QBzr/Explorer прилагаются и здесь.
Собственно других веских причин я затрудняюсь назвать. Я строго убежден, что лучшая DVCS еще не написана, и что у hg просто нет шансов подняться до более-менее паритета с git. Хотя на Windows платформе у hg много преимуществ, учитывая, что git на Windows -- это весьма тяжкое испытание.

воскресенье, 13 декабря 2009 г.

Модель "одна ветка = один каталог" в bzr

Немного истории

Современная система контроля версий Bazaar имеет свои корни в другой распределенной системе: GNU Arch. У системы Arch было несколько форков (разновидностей), одни из которых также назывался Bazaar (baz). Arch критиковали за излишнюю сложность интерфейса и трудность в освоении. Собственно современный Bazaar (bzr) появился как замена старому baz, и главной целью разработки нового bzr было именно упростить интерфейс пользователя системы, сделать систему удобной и лёгкой в использовании.

По большей части новый bzr добился своей цели (удобства использования). Однако при этом некоторые особенности модели системы Arch перекочевали в том или ином виде в новый Bazaar (bzr). И это накладывает свой отпечаток на работу самой системы и на работу пользователей с системой.

Следует заметить, что старый baz и новый bzr — обе эти системы разрабатывались и разрабатываются в основном за счет финансовой помощи компании Canonical Ltd, широко известной благодаря своему дистрибутиву Linux: Ubuntu.

Также следует отметить, что разработка нового bzr была задумана в ноябре 2004 года и официально началась в февраля 2005 года, на несколько месяцев ранее начала работ над git и hg. До первой половины 2006 года bzr развивался совершенно самостоятельно, как продолжатель baz. После стали очевидны успехи новых систем git и hg, особенно в плане показателей скорости, в результате чего внутренние алгоритмы bzr и форматы хранения данных в репозитории стали постепенно оптимизировать и улучшать в плане скорости работы. Однако несколько фундаментальных особенностей, унаследованных из baz/Arch, остались и до сегодняшнего дня. Понимание этих особенностей поможет вам более эффективно использовать bzr.

Унаследованные особенности

Основные особенности, унаследованные из Arch:
  • модель "каждая ветка живет в отдельном каталоге",
  • доступ к веткам возможен без специального сервера,
  • использование уникальных идентификаторов для файлов внутри системы.
Об уникальных идентификаторах файлов мы поговорим в другой статье, сейчас же рассказ пойдёт о модели "ветка=каталог", о её достоинствах и недостатках.

Каждая ветка живет в отдельном каталоге

Основная модель работы с ветками в bzr — это размещение каждой ветки в отдельном каталоге. У такого метода есть ряд плюсов и ряд минусов.

К плюсам можно отнести следующее. Каждая ветка однозначно присутствует как объект файловой системы, поэтому с ней можно оперировать средствами самой файловой системы, т.е. переименовывать, перемещать или удалять. Каждая ветка однозначно идентифицируется своим расположением, поэтому для доступа к ней достаточно использовать простой путь (для локального доступа) либо URL (для удаленного доступа), т.е. нет необходимости указывать URL + собственно имя ветки. Присутствие одной ветки в одном месте позволяет эффективно реализовать идею mainline. Каждая ветка хранит полную копию истории и полный набор рабочих файлов, что позволяет легко сравнивать и одновременно работать с несколькими ветками, которые содержат незафиксированные изменения.

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

Как вы могли заметить, я отнес один и тот же факт (каждая ветка хранит полную копию истории и полный набор рабочих файлов) и к плюсам и к минусам. На самом деле является ли это плюсом или минусом будет зависеть от конкретного проекта и того, как удобнее работать разработчикам.

Рассмотрим внимательно минусы. Они известны давно и для их нивелирования существует ряд методик эффективного использования bzr. Все указанные проблемы (каждая ветка занимает много места, долгое создание новой ветки, разделение одной рабочей копии) эффективно решаются при использовании разделяемого (или общего) репозитория (shared repository). Таким образом указанные минусы нивелируются использованием shared repository и остается лишь маленький недостаток: по умолчанию разделяемый репозиторий не создается сам по себе, его нужно создавать явно, командой init-repository.

Будем предельно честными: bzr позволяет эффективно работать с ветками, но по умолчанию создает обычные ветки. Это недостаток, который особенно сильно влияет на восприятие системы новичками, пришедших в bzr из других систем (git/hg), в которых всегда ветки живут в едином каталоге и представляют собой лишь виртуальные имена для разных линий истории проекта.

Из-за непонимания этого факта bzr много и не всегда оправданно критикуют.

Эффективное использование bzr: разделяемые репозитории

Что такое разделяемый репозиторий (shared repository)?

Для того, чтобы понять, что такое shared repository (разделяемый или общий репозиторий), сначала рассмотрим внутреннее устройство bzr-ветки. Каждая ветка содержит указатель на последнюю зафиксированную ревизию, что однозначно определяет всю историю ветки, поскольку история имеет вид направленного графа. Каждая ветка должна иметь репозиторий, в котором хранятся зафиксированные ревизии и состояние всех файлов ветки для каждой ревизии. Также ветка может иметь рабочую копию (а может и не иметь).

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

Поэтому такой репозиторий (shared repository) является общим для нескольких веток, либо можно сказать, что несколько веток разделяют (совместно используют) один и тот же репозиторий.

Следует запомнить фундаментальную разницу между ветками и репозиториями в bzr и репозиториями в git/hg. В bzr под репозиторием в большинстве случае понимают именно разделяемый репозиторий, каждая ветка внутри него — это отдельный каталог. В git/hg в одном каталоге живет и репозиторий, и ветки, и присутствует рабочая копия.

Локальная работа с ветками в репозитории

Для локальной работы рекомендуется создавать разделяемый репозиторий командой:
bzr init-repo PATH
После чего создавать копию главной ветки с сервера внутри репозитория:
cd PATH
bzr branch bzr://server/project/trunk
А уже для конкретной работы над новыми функциями создавать новую ветку на основе локальной копии trunk:
bzr branch trunk new-feature
cd new-feature
При такой работе каждая ветка будет иметь собственную рабочую копию, что позволит легко переходить между разными ветками и объединять изменения между ними. Такая методика работы подробно описывалась в наших предыдущих статьях (базовый набор команд и работа с ветками, см. оглавление).

Использование репозитория на сервере

Для хранения веток на сервере также полезно использовать разделяемые репозитории. Но зачастую сервер выступает просто хранилищем ревизий, поэтому рабочие копии для веток создавать не требуется. Это достигается командой:
bzr init-repo --no-trees URL
Опция командой строки --no-trees указывает, что по умолчанию рабочая копия для веток создаваться не будет.

Остальные операции с ветками можно производить как обычно.

Разделение одной рабочей копии между несколькими ветками

Как уже упоминалось выше в git/hg по умолчанию несколько веток живут в одном каталоге, который называют репозиторий, и в этом же каталоге присутствует рабочая копия, которую совместно используют все ветки. В каждый конкретный момент рабочая копия отражает состояние только текущей активной ветки. Будем называть такую модель работы "git-стиль".

Несмотря на то, что по умолчанию bzr использует другой стиль, однако мы может использовать и git-стиль, если так удобнее.

Для этого нужно создать отдельный репозиторий с указанием флага --no-trees, чтобы локальные ветки в этом репозитории не создавали ненужные рабочие копии. А затем нужно создать отдельную легковесную рабочую копию (lightweight checkout), не содержащую истории. Такая легковесная рабочая копия может быть создана даже за пределами репозитория.
bzr init-repo --no-trees PROJECT
bzr init PROJECT/trunk
bzr checkout --lightweight PROJECT/trunk work
В результате выполнения этой последовательности команд bzr создаст репозиторий в каталоге PROJECT, внутри репозитория создаст ветку trunk, и затем создаст рабочую копию в каталоге work.

Для создания новой ветки и одновременного переключения рабочей копии на нее можно использовать команду:
bzr branch --switch trunk new-feature
Переключение рабочей копии между ветками осуществляется командой switch:
bzr switch trunk
При переключении можно указать опцию --create-branch (-b), чтобы автоматически создать новую ветку:
bzr switch -b bugfix-123
Для получения списка веток в репозитории используйте команду:
bzr branches PROJECT
из плагина bzrtools.

Более подробный рассказ о нюансах работы с bzr в git-стиле будет дан в виде отдельной статьи.

Заключение

В этой статье я попытался описать как и почему в bzr используется модель "одна ветка в одном каталоге", привести доводы за и против такого подхода, а также показать пути эффективного использования bzr.

Как вы могли убедиться, bzr — это очень гибкая система, и она позволяет достичь намного большего при умелом использовании. Однако требует несколько большего времени на освоение.

Недостатком можно назвать лишь то, что по умолчанию bzr работает в не самом оптимальном режиме, поэтому для достижения эффективности требуется сделать несколько больше телодвижений. Следует ли это считать смертельным недостатком? Уверен, что нет.

Впрочем, каждому решать самому. Помните лишь, что каждая из современных распределенных систем (git/hg/bzr) имеет как достоинства, так и недостатки. Однако очень часто значимость как плюсов, так и минусов, не абсолютна, а относительна, и зависит от конкретного проекта и предпочитаемого стиля работы. И часто одни недостатки компенсируются другими достоинствами.

воскресенье, 22 ноября 2009 г.

Mainline: главная линия разработки и номера ревизий (Часть 3)

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

Концепция mainline

Концепция mainline разделяет ревизии на те, которые были зафиксированы непосредственно в конкретной ветке, и на все остальные, которые были присоединены из других веток (при помощи команды merge).

Благодаря тому, что в Bazaar используется модель "одна ветка в одном каталоге", то концепция mainline становится возможной и в некотором смысле логичной.

Наибольшее значение концепция mainline приобретает для главной ветки проекта (trunk), в которой должен находится только проверенный и рабочий код. При максимальном использовании mainline ни одна новая функция или багфикс не фиксируются напрямую в trunk, а всегда присоединяются (командой merge). При этом история в trunk представляет собой четкий список новых функций и улучшений.

Наиболее полно этот принцип используется самими разработчиками Bazaar. Если посмотреть на журнал ревизий ветки с кодом bzr, то мы увидим историю в виде списка улучшений и добавлений:
C:\work\Bazaar\bzr-2a\bzr.dev>bzr log -l10 --short
 4819 Canonical.com Patch Queue Manager 2009-11-20 [merge]
      (jam) Fix bug #485771,
        only change slashes on arguments that are being globbed.

 4818 Canonical.com Patch Queue Manager 2009-11-20 [merge]
      (jam) Add a developer doc describing dependencies for win32 builds

 4817 Canonical.com Patch Queue Manager 2009-11-20 [merge]
      (igc) Trivial formatting fix to merge help

 4816 Canonical.com Patch Queue Manager 2009-11-20 [merge]
      (igc) Explain that .bzrignore is implicitly added (Patrick Regan,
        #59608)

 4815 Canonical.com Patch Queue Manager 2009-11-19 [merge]
      (jam) Fix CommitBuilder.inv_sha1 when using record_iter_changes.

 4814 Canonical.com Patch Queue Manager 2009-11-19 [merge]
      (jam) Release the gil during some of the core groupcompress code
        paths.

 4813 Canonical.com Patch Queue Manager 2009-11-19 [merge]
      (jam) Remove a @needs_read_lock decorator from something that doesn't
        really need it.

 4812 Canonical.com Patch Queue Manager 2009-11-19 [merge]
      (Alexander Sack) Add --commit-time option to 'bzr commit'. (#459276)

 4811 Canonical.com Patch Queue Manager 2009-11-19 [merge]
      (Andrew Bennetts) Add 'Bazaar Contribution in Five Minutes'
        introduction to developer docs.

 4810 Canonical.com Patch Queue Manager 2009-11-18 [merge]
      (jam) Last few tweaks to get the win32 test suite to pass.

Use --include-merges or -n0 to see merged revisions.

Разделение ревизий на 2 группы

Как отмечено выше концепция mainline делит все ревизии в ветке на две неравные группы:
  • ревизии, непосредственно зафиксированные в конкретной ветке
  • ревизии, присоединенные из других веток командой merge
Последовательность ревизий из 1й группы образует "основную" историю ветки, или mainline. Иногда еще эту последовательность называют "left-hand history", поскольку при выводе журнала ревизий основная группа отображается начиная с крайней левой колонки, в то время как присоединенные ревизии выводятся в журнале с отступом.

Второе неравенство между группами ревизий заключается в том, что для "основной" истории ревизии нумеруются целыми числами, начиная с 1 для первой ревизии. Присоединенные ревизии нумеруются по сложной "точечной" схеме M.B.N, где
  • M — это основная ревизия, от которой отпочковалась ветка,
  • B — это условный порядковый номер ветки (чтобы различать несколько веток отпочковавшихся из одной и той же основной ревизии)
  • N — это номер ревизии в ветке, после отпочкования

Собственно номера ревизий — это одно из наиболее заметных проявлений концепции mainline. Рассмотрим теперь как mainline влияет на различные команды bzr.

Журнал ревизий

Как уже отмечалось, журнал ревизий выводит основные и присоединенные ревизии немного по-разному. Прежде всего присоединенные ревизии выводятся с отступом. А в последних версиях bzr присоединенные ревизии по умолчанию не отображаются (это сделано из соображений производительности). Для того, чтобы увидеть присоединенные ревизии необходимо использовать опцию командной строки --include-merges или -n0:
C:\work\Bazaar\bzr-2a\bzr.dev>bzr log -r-1 --short -n0
 4819 Canonical.com Patch Queue Manager 2009-11-20 [merge]
      (jam) Fix bug #485771,
        only change slashes on arguments that are being globbed.

       4818.1.1 John Arbash Meinel      2009-11-20
                Fix bug #485771. Only change '/' to '/' when expanding globs.

                The code we had would replace '/' even if it was in a quoted section,
                or if it was part of a simple argument that didn't have a glob.

При просмотре ревизий в GUI окне команды qlog присоединенные ревизии скрыты и помечены значком +:

qlog-test-collapsed

Щелчком мышки по значку + (либо нажатие стрелки вправо при использовании клавиатуры) раскрывает присоединенные ревизии:

qlog-test-expanded

Объединение двух веток

Как уже отмечалось ранее, ревизии разделены на две неравные группы. Поэтому история при объединении двух веток будет визуально различаться в зависимости от того как вы делаете merge, т.е. какая ветка будет основной, а какая присоединенной.

Рассмотрим несколько типовых случаев. Приведенные ниже примеры и рекомендации имеют смысл только если ваша команда разработчиков договорилась использовать парадигму mainline.

В следующих примерах подразумевается, что пользователь работает со своей локальной рабочей (функциональной) веткой, главная ветка (trunk) располагается на центральном сервере, и локально пользователь имеет копию главной ветки.

Неоконченная работа в функциональной ветке, присоединение изменений из другой ветки

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

В этом случае нормальным и правильным решением будет присоединение изменений из других веток в вашу рабочую ветку. При этом ваша ветка остается основной.

Объединение главной ветки и нового кода из функциональной ветки

Когда работа над новой функциональностью закончена и вы готовы объединить свой новый код с главной веткой, то необходимо помнить, что основная история в главной ветке должна оставаться неизменной. Поэтому вы должны присоединить свою ветку в главную ветку. Часто эту операцию называют land или landing (посадка, приземление).

Для выполнения объединения-приземления удобно использовать локальную копию главной ветки. Перед объединением вы обновляете локальную копию главной ветки (командой pull). Затем из каталога с копией главной ветки запускаете команду merge:
bzr merge ../my-work
После объединения вы проверяете результат, решаете конфликты если таковые имеются и фиксируете результат в копии главной ветки. Затем делаете push в главную ветку (на сервере).

Такой порядок действия хорошо работает в небольших командах, где каждый может делать push в главную ветку. В тех командах, где присоединением новых веток в главную занимается специальный человек (gatekeeper) или объединение производится специальной программой (так например в проекте Bazaar объединением с основной веткой занимается PQM — программа-работ, получающая инструкции через электронную почту), в этом случае целесообразно сделать merge из главной ветки в свою функциональную ветку перед подачей заявки на объединение с главной веткой. Это merge позволит вам исправить все возможные конфликты и следовательно упростит процедуру включения ваших изменений.

Когда объединение делать необязательно?

Продолжая тему объединения новой функциональности с главной веткой рассмотрим вопрос: всегда ли нужно использовать merge для этого?

Если ваша функциональная ветка является прямым продолжением главной ветки, то может возникнуть искушение сделать push прямо в главную ветку. В общем случае так делать не следует. Особенно если принятая политика вашей команды требует, чтобы перед включением новых изменений обязательно были запущены все автоматические тесты.

При отсутствии автоматических тестов у вас будет выбор. Но опять же — в общем случае делать прямой push не следует, особенно если в вашей ветке больше одной ревизии.

Если все ваши изменения уместились в одну ревизию, то в этом случае выбор за вами: делать merge или push. Операция merge может оказаться полезной тем, что вы сможете написать другой комментарий к вашим изменениям, более уместный в контексте главной ветки.

Push/pull и основная история

Следует знать и всегда помнить о том, что операции push и pull могут поменять основную историю ветки. В некотором смысле даже без вашего желания. Это происходит в тех случаях, когда одна ветка была объединена с другой.

Pull

Когда все ревизии из вашей рабочей (функциональной) ветки присоединены в основную ветку, то pull из основной ветки в вашу ветку приведет к тому, что ваша ветка станет полной копией другой ветки. Все ваши ревизии уже присоединены в основную ветку, так что вы ничего не теряете.

Push

Наиболее частая ошибка при объединении функциональной ветки с главной веткой, это когда merge делается в функциональную ветку (вместо копии главной ветки). В этом случае push из функциональной ветки в главную ветку становится возможным. Но делать такой push — очень плохая идея, потому что при этом изменяется нумерация ревизий в главной ветке: push при этом меняет mainline главной ветки на mainline функциональной ветки. Так делать не следует. Как было описано выше правильно делать merge в локальную копию главной ветки и делать push оттуда.

Хотя подобный push не является фатальным сам по себе, его следует избегать. Потому что если кто-то другой зафиксирует новую ревизию после того, как основная история была изменена, это превратится в проблему.

append_revisions_only

В bzr существует способ запретить изменение основной истории ветки.

Если при создании ветки указать опцию --append-revisions-only, то для такой ветки устанавливается флаг, запрещающий изменение основной истории за исключением добавления новых ревизий. Т.е. запрещаются операции uncommit и pull/push, если в результате pull/push существующие mainline ревизии могут быть заменены другими с одинаковыми номерами.

Флаг append_revisions_only можно установить и позднее, после того как ветка создана. Для этого необходимо добавить следующую строку в файл конфигурации branch.conf (он находится в .bzr/branch/branch.conf):
append_revisions_only = True

Установка такого флага возможна и для веток на Launchpad.net, хотя и не совсем тривиальным способом: вам понадобится использовать утилиту hitchhicker.

Заключение

В этой статье я попытался описать ключевые моменты, о которых необходимо знать для эффективного использования парадигмы mainline.

Еще раз хочу отметить, что идея mainline уникальна для bzr и отсутствует в других распределенных системах контроля версий (git, hg). У идеи mainline есть свои достоинства и недостатки, и правильное использование mainline требует определенной внимательности и соглашений в команде разработчиков.

пятница, 25 сентября 2009 г.

Bazaar 2.0 и новый формат репозитория по умолчанию

Сегодня 25 сентября и со дня на день всё прогрессивное человечество ожидает выхода новой версии bzr 2.0. Как видно из названия, эта версия не просто очередная версия bzr, одна из тех, что выходят почти каждый  месяц. Это версия 2.0 (три восклицательных знака).

Одно из ключевых изменений в версии 2.0 — это новый формат репозитория, используемый по умолчанию, который называется 2a. Именно это изменение может стать серьезным камнем преткновения для некоторых пользователей, как оно почти стало для меня.

Проблема

Bazaar имеет заслуженную репутацию системы, в которой существует зоопарк форматов репозиториев. В настоящий момент число форматов превышает 10. История появления каждого формата отмечает этапы развития системы и путь, который bzr прошел ради достижения скорости работы, сравнимой с такими лидерами как Mercurial и Git.

Само по себе такое число форматов ни о чем плохом не говорит: все форматы поддерживаются по сей день, новые версии bzr без проблем умеют работать с репозиториями в старых форматах, хотя в ряде случаев рекомендуют обновить формат на более новый по причине морального старения. Да и новые форматы обычно более компактны и занимают меньше места на диске, плюс bzr работает с ними заметно быстрее. Проблема не в их числе, проблема в том, что существуют две группы форматов, взаимно не заменяемые.

Речь идет о различии между обычными форматами и так называемыми rich-root форматами. По историческим причинам rich-root формат появился для поддержки одной долгожданной функции bzr, которая впрочем до сих пор не реализована. Отличие между простыми форматами и rich-root заключается в наличии дополнительных метаданных о ветках. Форматы rich-root никогда не были рекомендуемыми, и не являлись форматом по умолчанию. Более того, поскольку дополнительная информация rich-root формата не может быть сохранена в простом формате, то вы не можете перейти от rich-root к простому формату. Вообще. Переход от простых форматов к rich-root возможен всегда. Причем, вы не сможете даже сделать pull или merge из rich-root в обычную ветку. Собственно это и составляет проблему: односторонний переход из одной группы форматов в другую.

Ящик пандоры открыл популярный плагин bzr-svn, который первым стал активно использовать формат rich-root при конверсии svn репозитория в bzr. Причины такого решения целиком логичные, однако имели далеко идущие последствия. Каждый новый формат в серии bzr 1.x всегда имел пару реализаций: простую и rich-root. Много раз подымался вопрос об их объединении в единый формат, однако по ряду причин это сделано только в новом формате 2a.

Новый формат bzr 2a поддерживает только rich-root, поэтому новые пользователи будут избавлены от имеющейся дихотомии.

Однако, все существующие репозитории и ветки должны быть либо обновлены до 2a или хотя бы до rich-root, чтобы избежать проблемы несовместимости форматов.

Пример несовместимости

Создадим ветку в формате pack-0.92 (основной формате в серии bzr 1.x, обычный не rich-root).

C:\work\bzr-day\Formats>bzr init 0.92 --format=pack-0.92
Created a standalone tree (format: pack-0.92)

C:\work\bzr-day\Formats\0.92>bzr ci --unchanged -m 1
Committing to: C:/work/bzr-day/Formats/0.92/
Committed revision 1.


Сделаем копию этой ветки и сконвертируем ее в формат 2a.

C:\work\bzr-day\Formats>bzr branch 0.92 2a
Branched 1 revision(s).

C:\work\bzr-day\Formats\2a>bzr upgrade --format=2a
starting upgrade of file:///C:/work/bzr-day/Formats/2a/
making backup of file:///C:/work/bzr-day/Formats/2a/.bzr
  to file:///C:/work/bzr-day/Formats/2a/backup.bzr
starting repository conversion
repository converted
finished

C:\work\bzr-day\Formats\2a>bzr info
Standalone tree (format: 2a)
Location:
  branch root: .

Related branches:
  parent branch: C:/work/bzr-day/Formats/0.92

C:\work\bzr-day\Formats\2a>bzr ci --unchanged -m 2a
Committing to: C:/work/bzr-day/Formats/2a/
Committed revision 2.

Зафиксируем еще одну ревизию в первой ветке:

C:\work\bzr-day\Formats\0.92>bzr commit --unchanged -m 2-0.92
Committing to: C:/work/bzr-day/Formats/0.92/
Committed revision 2.

И попробуем сделать объединение. Объединение из обычного формата в 2a работает без проблем:

C:\work\bzr-day\Formats\2a>bzr merge ../0.92
All changes applied successfully.

А вот в обратную сторону не работает вовсе:

C:\work\bzr-day\Formats\0.92>bzr merge ../2a
bzr: ERROR: KnitPackRepository('file:///C:/work/bzr-day/Formats/0.92/.bzr/repository/')
is not compatible with
CHKInventoryRepository('file:///C:/work/bzr-day/Formats/2a/.bzr/repository/')
different rich-root support


В последней строке явно виден корень проблемы: different rich-root support.

Проблема усугубляется тем, что конвертация из простого формата в rich-root может произойти неявно и без вашего ведома. Например, когда вы делаете копию не-rich-root ветки в разделяемый репозиторий (shared repository) в rich-root формате:

C:\work\bzr-day\Formats>bzr init-repo --2a shared-repo
Shared repository with trees (format: 2a)
Location:
  shared repository: shared-repo

C:\work\bzr-day\Formats\shared-repo>bzr branch ../0.92 trunk
Branched 2 revision(s).

C:\work\bzr-day\Formats\0.92>bzr merge ../shared-repo/trunk
bzr: ERROR: KnitPackRepository('file:///C:/work/bzr-day/Formats/0.92/.bzr/repository/')
is not compatible with
CHKInventoryRepository('file:///C:/work/bzr-day/Formats/shared-repo/.bzr/repository/')
different rich-root support

Как узнать текущий формат ветки/репозитория

Команда bzr info -v отображает различную информацию о ветке/репозитории и в том числе формат репозитория.

C:\work\bzr-day\Formats\0.92>bzr info -v
Standalone tree (format: pack-0.92)
Location:
  branch root: .

Related branches:
  submit branch: C:/work/bzr-day/Formats/2a

Format:
       control: Meta directory format 1
  working tree: Working tree format 4
        branch: Branch format 6
    repository: Packs containing knits without subtree support
...

В строке repository описан детальный формат. Если там написано without subtree support — это обычный не-rich-root формат.

C:\work\bzr-day\Formats\2a>bzr info -v
Standalone tree (format: 2a)
Location:
  branch root: .

Related branches:
  parent branch: C:/work/bzr-day/Formats/0.92
  submit branch: C:/work/bzr-day/Formats/0.92

Format:
       control: Meta directory format 1
  working tree: Working tree format 6
        branch: Branch format 7
    repository: Repository format 2a - rich roots, group compression and chk inventories
...


Заметьте, что для 2a в описании формата присутствует упоминание rich roots.

Что делать

С первым вопросом русской интеллигенции мы разобрались выше, теперь перейдем ко второму вопросу. Ответ на него имеет несколько вариантов в зависимости от конкретной ситуации.

1. Конвертировать все свои ветки и репозитории в формат 2a

В долгосрочной перспективе наиболее правильное решение — это конвертация всех ваших репозиториев в формат, поддерживающий rich-root. В первую очередь в формат 2a.
Формат 2a поддерживается в bzr, начиная с версии 1.16. Поэтому если на всех компьютерах в вашей организации установлена достаточная свежая версия bzr вы можете пойти этим путём.

Рекомендуется сделать тестовое обновление на локальной машине. Перед обновлением целесообразно запустить команду bzr reconcile для исправления возможных нестыковок внутри репозитория. Затем кто-то один из вашей команды должен сделать обновление веток на центральном сервере, а затем остальные сделают новую копию главной ветки на свои компьютеры, или обновят все свои ветки в формат 2a.
Подробная инструкция по обновлению.
2. Конвертировать свои ветки в формат rich-root

Если по ряду причин в вашем ведении находятся компьютеры со старой версией bzr, либо вы используете сторонние продукты, которые зависят от старых версий bzr, то вы можете рассмотреть вариант обновления до формата rich-root-pack, который совместим с 2a. Рекомендации по последовательности обновления те же самые.

3. Не использовать bzr 2.0 и выше

Если по ряду причин вы не можете обновить часть компьютеров и не считаете целесообразным обновлять все ветки и репозитории в rich-root формат, то, возможно, вам стоит принять волевое решение не обновлять ни на одном подведомственном вам компьютере bzr до версии 2.0. Последняя стабильная версия из серии bzr 1.x — это bzr 1.18.

Однако рано или поздно перейти придётся. Хотя бы потому, что в новых версиях чинят старые баги.

4. Использовать специальный плагин для установки старого формата по умолчанию

Я написал маленький плагин format1, который устанавливает старый не-rich-root формат pack-0.92 в качестве формата по умолчанию для bzr. После установки этого плагина при каждом запуске bzr форматом по умолчанию будет устанавливаться pack-0.92. Поэтому все создаваемые с нуля новые ветки и разделяемые репозитории (что самое важное!) будут иметь формат pack-0.92. При этом пользователь может принудительно выбрать другой формат через опции командной строки.

Ветка плагина располагается на Launchpad: https://code.launchpad.net/~bialix/+junk/format1

Установка плагина: как обычно, поместите копию ветки в ваш каталог plugins.

ПРЕДУПРЕЖДЕНИЕ ОБ ОТКАЗЕ ОТ ОТВЕТСТВЕННОСТИ: написанный мною плагин должен работать корректно, однако 100% гарантию я давать не буду. Поэтому используйте его на свой страх и риск, либо не используйте вовсе, а рассмотрите предыдущие озвученные варианты решения проблемы.

Выводы

Переход на использование нового bzr 2.0 влечёт за собой и переход на новый формат 2a. Будьте внимательны и донесите до сведения каждого участника вашей команды все последствия такого перехода и скоординируйте обновление всех ваших веток.

понедельник, 14 сентября 2009 г.

Mainline: главная линия разработки и номера ревизий (Часть 2)

Продолжаем разговор об одной специфичной особенности bzr, которую вы не найдете ни в одной другой распределенной системе контроля версий. Мы рассматриваем понятие mainline (главная линия разработки), его связь с номерами ревизий, и каким образом mainline влияет на работу с несколькими ветками.

Откуда есмь пошло понятие mainline

В английском языке mainline означает основную дорогу, магистраль, основную колею участка железной дороги.
Понятие mainline пришло в Bazaar из его предшественника Arch. В Arch это понятие использовалось, чтобы разделить ревизии, зафиксированные в этой конкретной ветке, от ревизий, присоединенных (merged) из других веток. В таком же контексте mainline используется и в Bazaar.

Синонимом понятия mainline (главная линия или главная ветка) в распределенных системах можно считать ствол (trunk) в централизованных системах (svn). Однако при этом промежуточные стадии разработки производятся в отдельных ветках, а в главную ветку (trunk) попадает уже готовый отлаженный результат работы. В этом случае trunk теоретически всегда находится в работоспособном состоянии: программа заведомо компилируется и работает. Подробное изложение такого метода разработки можно найти в документе Ultimate Quality Development System (UQDS).

Реально, mainline в Bazaar — это фактически закрепленная на уровне системы контроля версий модель разработки с основной (центральной) веткой, в которая содержит законченные результаты работы, и множества  рабочих веток (features branches — ветки для разработки новых функций), которые собственно используются разработчиками.

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

Недостатком встроенной поддержки парадигмы mainline является то, что отключить эту поддержку в Bazaar нет возможности, поэтому для нормальной работы с системой пользователь должен так или иначе следовать этой парадигме. В противном случае журнал ревизий будет не так легко анализировать.

Как mainline влияет на вывод журнала ревизий

Дополнительное (негативное) влияние парадигма mainline косвенно оказывает на быстродействие некоторых операций, в которых участвуют составные "точечные" номера ревизий (dotted revno), например, ревизия 2.1.1. Для однозначного вычисления "точечного" номера ревизии Bazaar должен проанализировать полный граф ревизий на достаточную глубину, чтобы найти ревизию, после которой ветки разошлись.

В связи с этим разработчики Bazaar, начиная с версии bzr 1.14, пошли на небольшую хитрость: по умолчанию "точечные" ревизии в журнале не отображаются, что позволяет избежать затрат на вычисление их номеров. При этом у пользователя остается возможность принудительно включить их вывод при помощи соответствующей опции командной строки.

Чтобы было понятнее, рассмотрим основные форматы вывода журнала ревизий, которые нам предлагает Bazaar.
  • bzr log --long — формат вывода журнала по умолчанию; отображается детальная информация о ревизии в несколько строк: условный номер ревизии, теги, автор(ы), короткое имя ветки (branch nick), дата, полный текст комментария к ревизии. Пример (из знакомой нам ветки Test):
C:\work\bzr-day\Basic-commands\Test>bzr log -r-1
------------------------------------------------------------
revno: 4 [merge]
committer: Базарный день <ru_bzr@googlegroups.com>
branch nick: Test
timestamp: Tue 2009-09-08 23:50:01 +0300
message:
  Объединение с веткой Experimental
------------------------------------------------------------
Use --include-merges or -n0 to see merged revisions.

  • bzr log --short — "краткий" формат вывода: в одну строку выводится условный номер ревизии, автор, дата; ниже выводится полный комментарий к ревизии. Пример:
C:\work\bzr-day\Basic-commands\Test>bzr log -r-1 --short
    4 Базарный день     2009-09-08 [merge]
      Объединение с веткой Experimental

Use --include-merges or -n0 to see merged revisions.
  • bzr log --line — наиболее компактный формат вывода: в одну строку выводится условный номер ревизии, автор, дата и начало комментария к ревизии. Пример:
C:\work\bzr-day\Basic-commands\Test>bzr log -r-1 --line
4: Базарный день 2009-09-08 [merge] Объединение с веткой Experimental

До версии bzr 1.14 log --long всегда отображал присоединенные ревизии, а log --short и log --line не умели этого. Теперь все форматы умеют отображать присоединенные ревизии при запуске команды log с опцией -n0 или --include-merges. Например:

C:\work\bzr-day\Basic-commands\Test>bzr log --line -n0
4: Базарный день 2009-09-08 [merge] Объединение с веткой Experimental
  2.1.1: Базарный день 2009-09-08 Скорректирован файл goodbye.txt в ветке Experimental
3: Базарный день 2009-09-08 Скорректирован файл foo.txt в ветке Test
2: Базарный день 2009-09-08 Внесены изменения для иллюстрации команд status и diff
1: Базарный день 2009-09-08 Начальное состояние файлов

Итак, мы можем видеть, что сегодня журнал по умолчанию отображает только ревизии, соответствующие mainline. Поэтому, если ваш проект не следует этой парадигме, вы всегда должны запускать команду log с включенной опцией отображения присоединенных ревизий. (Этого можно достичь при помощи aliases). Аналогичная картина и с GUI командой qlog (из плагина QBzr): после запуска этой команды пользователь видит только mainline-ревизии, а присоединенные ревизии свернуты. Для разворачивания/отображения этих ревизий пользователь должен щелкнуть мышкой по значку + в круглом узле на графе ревизий (либо использовать стрелки влево-вправо на клавиатуре), см. снимок с экрана ниже.

qlog-test-collapsed

Рисунок 1. Отображение графа ревизий после запуска: только mainline ревизии

qlog-test-expanded

Рисунок 2. Развернутый узел с присоединенными ревизиями

В следующей части этой статьи мы рассмотрим как mainline влияет на команды merge, commit и push. Также мы попытаемся сформулировать ряд советов по правильному использованию парадигмы главной линии разработки (mainline).

вторник, 8 сентября 2009 г.

Mainline: главная линия разработки и номера ревизий (Часть 1)

Сегодня речь пойдет об одной специфичной особенности bzr, которую вы не найдете ни в одной другой распределенной системе контроля версий. Мы рассмотрим понятие mainline (главная линия разработки), его связь с номерами ревизий, и каким образом mainline влияет на работу с несколькими ветками.

Номера ревизий в распределенной системе

Прежде всего необходимо четко понимать и помнить, что в распределенных системах контроля версий для однозначной идентификации любой ревизии необходимо применять некие уникальные идентификаторы. Простая нумерация ревизий 1,2,3,… для этого не подходит, поскольку идентификаторы должны быть уникальны в глобальном смысле, а простые номера уникальны только в пределах одной физической копии репозитория (что вполне подходит для централизованных систем типа svn).

Поэтому все современные распределенные системы применяют уникальные идентификаторы. Так Monotone, Git и Mercurial используют в качестве уникального идентификатора ревизии SHA-1 хэш от данных самой ревизии. Bazaar тоже использует уникальные идентификаторы для ревизий, однако эти идентификаторы представляют произвольную строку и нет требования, чтобы идентификатор был основан на данных самой ревизии.

Использование длинных и/или абстрактных идентификаторов в большинстве случаев не является оптимальным способом адресации ревизии для простых смертных. Поэтому разработчики Bazaar решили, что внутри системы будут использоваться уникальные идентификаторы, а пользователи системы будут большую часть времени оперировать с условными номерами ревизий. При этом в Bazaar остается возможность использовать собственно уникальные идентификаторы.

Номера ревизий в Bazaar имеют условный характер и имеют смысл только в контексте конкретной ветки, с которой производятся какие-то действия и в большинстве случаев эти номера стабильны и не меняются.

Принципы формирования номеров ревизий в Bazaar

Каждой ревизии, которую вы фиксируете в своей ветке присваивается свой порядковый номер (revno), начиная с 1. Эти номера неизменны для конкретной ветки.

Когда вы объединяете свою ветку с другой, то должны зафиксировать результат объединения в виде новой ревизии. Эта ревизия получит свой порядковый номер как и раньше. А вот ревизии, которые были добавлены в вашу ветку в результате объединения, получат специальные новые "номера", состоящие из 3х чисел, разделенных точками (так называемые dotted revno).

В качестве примера вернемся к нашей прошлой статье Начинаем работу с bzr: базовый набор команд (Часть 2). Я приведу кусочек вывода команды bzr log для ветки после объединения:
C:\work\bzr-day\Basic-commands\Test>bzr log -n0 
------------------------------------------------------------ 
revno: 4 [merge] 
committer: Базарный день <ru_bzr@googlegroups.com>
branch nick: Test 
timestamp: Tue 2009-09-08 23:50:01 +0300 
message: 
  Объединение с веткой Experimental     
------------------------------------------------------------ 
    revno: 2.1.1
    committer: Базарный день <ru_bzr@googlegroups.com>
    branch nick: Experimental 
    timestamp: Tue 2009-09-08 23:48:42 +0300 
    message: 
      Скорректирован файл goodbye.txt в ветке Experimental 
------------------------------------------------------------ 
revno: 3 
committer: Базарный день <ru_bzr@googlegroups.com>
branch nick: Test 
timestamp: Tue 2009-09-08 23:49:13 +0300 
message: 
  Скорректирован файл foo.txt в ветке Test 
------------------------------------------------------------
Обратите внимание на строки, начинающиеся с "revno:" — они показывают номер ревизии.

Можно видеть, что после ревизии номер 3 было произведено объединение, результат объединения зафиксирован в ревизии под номером 4. В результате объединения появилась ревизия из другой ветки, ей был присвоен номер 2.1.1.

Ревизии с целыми номерами (без точек) образуют главную линию разработки вашей ветки (mainline). Ревизии, присоединенные из других веток (merged revisions) являются частью полной истории ветки, но не входят в главную линию и имеют составной номер ревизии, разделенный точками (X.Y.Z).

Как узнать уникальные идентификаторы ревизий

Команда bzr log способна отображать настоящие глобально-уникальные идентификаторы ревизий при запуске с дополнительной опцией --show-ids:
C:\work\bzr-day\Basic-commands\Test>bzr log -n0 --show-ids -l3 
------------------------------------------------------------ 
revno: 4 [merge] 
revision-id: ru_bzr@googlegroups.com-20090908205001-h9q4wxqx76bi0j6u
parent: ru_bzr@googlegroups.com-20090908204913-43cyv2j60fva7w8g
parent: ru_bzr@googlegroups.com-20090908204842-5c0hseh1g4zyrzwx
committer: Базарный день <ru_bzr@googlegroups.com>
branch nick: Test 
timestamp: Tue 2009-09-08 23:50:01 +0300 
message: 
  Объединение с веткой Experimental     
------------------------------------------------------------ 
    revno: 2.1.1 
    revision-id: ru_bzr@googlegroups.com-20090908204842-5c0hseh1g4zyrzwx
    parent: ru_bzr@googlegroups.com-20090908204210-qegq6pfotpffqda6
    committer: Базарный день <ru_bzr@googlegroups.com>
    branch nick: Experimental 
    timestamp: Tue 2009-09-08 23:48:42 +0300 
    message: 
      Скорректирован файл goodbye.txt в ветке Experimental 
------------------------------------------------------------ 
revno: 3 
revision-id: ru_bzr@googlegroups.com-20090908204913-43cyv2j60fva7w8g
parent: ru_bzr@googlegroups.com-20090908204210-qegq6pfotpffqda6
committer: Базарный день <ru_bzr@googlegroups.com>
branch nick: Test 
timestamp: Tue 2009-09-08 23:49:13 +0300 
message: 
  Скорректирован файл foo.txt в ветке Test 
------------------------------------------------------------
Строки, начинающиеся на "revision-id:" собственно отображают идентификаторы ревизий. Так, ревизии номер 4 в этой ветке соответствует уникальный идентификатор "ru_bzr@googlegroups.com-20090908205001-h9q4wxqx76bi0j6u".

Можно заметить, что Bazaar использует данные об авторе ревизии и дате фиксации плюс некоторые случайные данные для формирования уникального идентификатора. Однако, как я упоминал ранее, формат и содержание идентификатора — произвольные.

Что означают цифры в номере присоединенной ревизии

Правило образования номеров для присоединенных ревизий следующее:
  • первая цифра означает номер ревизии в главной ветке, от которой отпочковалась побочная ветка
  • вторая цифра означает порядковый номер побочной ветки (начиная с 1)
  • третья цифра означает порядковый номер ревизии в побочной ветке, после того, как история разошлась.
Взглянем на граф ревизий, визуализированный при помощи команды qlog из плагина QBzr:

граф ревизий
Ревизия 2.1.1 отпочковалась от ревизии 2 в основной ветке, имеем всего одну побочную ветку (Experimental), и одну ревизию в побочной ветке. Если бы в побочной ветке Experimental были бы еще ревизии, то они были бы пронумерованы как 2.1.2, 2.1.3 и т.д.

В следующей части статьи мы рассмотрим, каким образом концепция главной линии разработки (mainline) влияет на работу с Bazaar.

Примеры к статье можно найти на Launchpad.net: ветка Test, ветка Experimental.

понедельник, 23 февраля 2009 г.

Установка bzr

Для установки bzr в вашей системе нужно выбрать соответствующий пакет или дистрибутив из перечисленных на странице Download.
Кратко рассмотрим варианты установки для различных операционных систем.

Установка из исходных кодов

Система контроля версий Bazaar написана на языке программирования Python (Питон), что облегчает ее установку и использование: достаточно иметь установленный интерпретатор языка Python в вашей системе (версии 2.4–2.6, рекомендуется 2.5). Опытные пользователи Python могут использовать стандартное "заклинание": python setup.py install для установки. Более подробно об опциях установки можно прочитать в файле INSTALL.

Установка для ОС Linux

Для большинства популярных дистрибутивов Linux имеются готовые пакеты для установки bzr. Каждый конкретный дистрибутив имеет свои особенности, поэтому ознакомьтесь с детальными инструкциями  на странице DistroDownloads.

Если вы используете Ubuntu Linux, то скорее всего bzr уже будет установлен в вашей системе. Однако вам имеет смысл ознакомиться с процессом обновления bzr, для того, чтобы регулярно устанавливать свежую версию. Разработка bzr идет достаточно интенсивно и примерно каждый месяц выпускается новая версия. Новые версии как правило работают быстрее и содержат значительное количество исправлений известных ошибок.

Установка для ОС Windows

Наиболее оптимальным и рекомендуем способом установки bzr в ОС Windows является использование инсталлятора автономной версии (Windows Standalone Installer). Автономная версия содержит скомпилированную программу bzr.exe для Windows, и поставляется с набором всех необходимых библиотек. Также инсталлятор автономной версии предлагает установить набор популярных плагинов для bzr, а также программу TortoiseBzr, которая предоставляет интеграцию bzr-команд в Explorer.

Альтернативным вариантом установки является использование инсталляторов питон-версии bzr (python installer). Для работы питон-версии вам потребуется установленный интерпретатор Python (версии 2.4–2.6, рекомендуется 2.5), а также набор дополнительных библиотек. См. http://bazaar-vcs.org/WindowsInstall для дополнительных инструкций.

В большинстве случаев выбор автономной версии bzr.exe — это оптимальный вариант. Однако, если вам понадобится интегрировать bzr с другими питон-программами, то установка питон-версии может оказаться единственным работающим вариантом.

Установка для ОС Mac OS X

Для компьютеров фирмы Apple также имеются готовые инсталляторы, а также специальные репозитории портированных программ: MacPorts и Fink. См. ссылки на подробные инструкции на странице Download.

Bazaar: зачем и почему

Сегодня о распределенных системах контроля версий слышали и знают многие. Несмотря на то, что svn по-прежнему лидирует и все еще является наиболее часто используемой системой контроля версий (особенно в корпоративном секторе), однако распределенные системы нового поколения продолжают набирать популярность.

К распределенным системам нового поколения относят Git (Гит), Mercurial (Меркуриал) и Bazaar (Базар). Все три системы появились на свет более-менее в одно время (конец 2004 – начало 2005 года). Список современных распределенных систем контроля версий также дополняют Darcs и Monotone.

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

Развитию распределенных систем контроля версий способствуют два основных фактора:
  • бурное развитие глобальной сети интернет
  • наличие доступных по цене переносных компьютеров (ноутбуков и нетбуков)
Первый фактор способствует образованию множества географически распределенных команд, работающих над одним проектом; в первую очередь это касается проектов с открытым кодом (Open source projects). Второй фактор позволяет разработчикам использовать долгие путешествия (поезд, самолет) для того, чтобы продолжать работать над своими проектами. Поскольку полная копия репозитория всегда доступна локально (на жестком диске компьютера разработчика) и практически все операции можно делать без соединения с сервером, то это с одной стороны позволяет достичь более высокой скорости работы, а с другой стороны работать в условиях отсутствия подключения к сети.

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

Гит и Меркуриал изначально создавались для работы над ядром операционной системы Linux (Линукс), поэтому одним из главных требований для них была возможность адекватной работы с набором файлов с исходными кодами Линукс. Одной из главных целей при этом стало достижение максимальной скорости работы с огромным количеством файлов.

Базар же изначально проектировался как замена распределенной системы контроля версий первого поколения (GNU Arch) и главной целью было создание удобного и дружественного интерфейса пользователя. Оптимизацией скорости работы этой системы начали заниматься несколько позднее, используя в качестве наглядного примера Гит и Меркуриал. В то же время в Базаре изначально большое внимание уделяется идеям расширяемости и обратной совместимости. Одной из ключевых особенностей Базара является привязка уникального идентификатора к каждому версионированному файлу, каталогу или символической ссылке, что позволяет легко и эффективно отслеживать переименования файлов и каталогов. В своем арсенале Базар имеет поддержку для множества различных моделей работы (от полностью распределенной до централизованной), Базар имеет поддержку для работы с репозиториями через множество различных протоколов (локальный файловый доступ, http/https, sftp, ftp, специальный эффективный bzr-протокол). Все это делает Базар очень гибкой системой, способной легко адаптироваться к различным требованиям. Но в то же время эта гибкость может озадачить начинающих пользователей, поскольку требует внимательного изучения руководства пользователя.

В последующих статьях обязательно будет рассказано о разных аспектах использования Базара.
Если же у вас появятся конкретные вопросы по использованию Базара, вы всегда можете задать их в дискуссионной группе ru_bzr.

Об этом блоге

Блог "Базарный день" посвящен вопросам использования распределенной системы контроля версий Bazaar. В этом блоге мы будем рассказывать о различных приемах работы с bzr, тонкостях, хитростях и трюках. Также достаточно времени будем уделять объяснению терминологии. Таким образом блог ориентирован на начинающих и продолжающих пользователей. Надеюсь, что и эксперты смогут подчерпнуть здесь что-то интересное для себя. Либо сами захотят написать о своем опыте. Формат блога ориентирован на относительно короткие статьи-рецепты, которые мы постараемся публиковать примерно раз в неделю. Подписывайтесь на нашу ленту новостей, чтобы всегда узнавать о новых статьях первыми. :-)