пятница, 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. Будьте внимательны и донесите до сведения каждого участника вашей команды все последствия такого перехода и скоординируйте обновление всех ваших веток.

Комментариев нет:

Отправить комментарий