Немного истории
Современная система контроля версий 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.
По большей части новый 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 много и не всегда оправданно критикуют.
К плюсам можно отнести следующее. Каждая ветка однозначно присутствует как объект файловой системы, поэтому с ней можно оперировать средствами самой файловой системы, т.е. переименовывать, перемещать или удалять. Каждая ветка однозначно идентифицируется своим расположением, поэтому для доступа к ней достаточно использовать простой путь (для локального доступа) либо 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 в одном каталоге живет и репозиторий, и ветки, и присутствует рабочая копия.
Для обычных веток репозиторий находится в том же каталоге, что и сама ветка. Однако это не обязательно. Репозиторий может находиться и за пределами каталога с веткой, в одном из родительских каталогов. Такой отдельный репозиторий может хранить зафиксированные ревизии и состояния файлов для нескольких веток, находящихся внутри репозитория. А поскольку история веток по большей части совпадает, то в результате место расходуется гораздо более экономно, чем в случае когда каждая ветка хранит полную копию всего репозитория. Каждая ветка, создаваемая внутри разделяемого репозитория, автоматически находит и начинает использовать этот репозиторий.
Поэтому такой репозиторий (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 в 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) имеет как достоинства, так и недостатки. Однако очень часто значимость как плюсов, так и минусов, не абсолютна, а относительна, и зависит от конкретного проекта и предпочитаемого стиля работы. И часто одни недостатки компенсируются другими достоинствами.
Как вы могли убедиться, bzr — это очень гибкая система, и она позволяет достичь намного большего при умелом использовании. Однако требует несколько большего времени на освоение.
Недостатком можно назвать лишь то, что по умолчанию bzr работает в не самом оптимальном режиме, поэтому для достижения эффективности требуется сделать несколько больше телодвижений. Следует ли это считать смертельным недостатком? Уверен, что нет.
Впрочем, каждому решать самому. Помните лишь, что каждая из современных распределенных систем (git/hg/bzr) имеет как достоинства, так и недостатки. Однако очень часто значимость как плюсов, так и минусов, не абсолютна, а относительна, и зависит от конкретного проекта и предпочитаемого стиля работы. И часто одни недостатки компенсируются другими достоинствами.