solovyov.net

Bazaar: hate and... hate

6 min read · vcs, hg, bzr

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

Я пользовался им три месяца (мы перешли на меркуриал, pure win) и теперь имею все основания заявить, что базар - плох. Как по фичам, так и по интерфейсу. Как снаружи, так и внутри. И тут будут перечислены те моменты, которые я считаю глупыми, неудачными, неадекватными и т.п. Это не сравнение базара с нормальной системой контроля версий, это не спор с кем-либо - это просто перечисление проблем, чтоб в следующий раз кто-то, кто будет посматривать на базар, возможно напоролся на эту статью и сказал - “нет-нет-нет, Девид Блейн, такой магии нам не надо”.

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

Номера ревизий

Господа разработчики как-то подумали, что реальные идентификаторы ревизий будет использовать неудобно (и правда, они даже хуже, чем sha1-хеши в хг и гите - это емейл автора + дата + какая-то случайная строка), и надо сделать что-то покороче и поудобнее. Вроде бы неплохая идея, в меркуриале тоже такое есть. Но в базаре в этом месте настоящий хайтек - он пытаются сделать так, чтоб во всех репозиториях эти номера не менялись. Кроме того, настоящий айдишник стараются не светить (нужно сказать bzr log --show-ids). Идея в том, что мы используем просто короткий номер и довольны.

Но это же не работает! Они-то пытаются получить одни и те же айдишники везде, но в результате это не получается по куче причин, и запомнить какое-то небольшое количество цифр (номер в хг или часть sha1-хеша в хг/гите) ты не можешь, и приходится слать весь этот дурацкий номер через IM/мыло (можно пойти туда, где нет вайфая и тогда придëтся диктовать всю эту 40+-значную дуру).

И это не всë!

mainline

Есть еще отличная идея такой себе главной ветки разработки, где видны, скажем, мержи каких-то веток гейткипером. Т.е. bzr log показывает только мержи, а все изменения спрятаны. Чтобы их увидеть, надо написать bzr log -n0 и тогда случается чудо - номера ревизий показываются совершенно другие. Линейные, просто больше. Типа, была ревизия номер 893, а теперь она 1792. Глобально и надëжно.

Если -n0 не передавать, но посмотреть что-то, что показывает эти спрятанные ревизии (например, annotate), то номера показываются в формате 326.8.9. Seriously, WTF? Эти клëвые смешные номерочки тоже имеют свойство со временем меняться. В смысле, на них вообще положиться нельзя. :(

Пример из реального проекта (имена и мессаги я заменил на выдуманные):

piranha@gto ~/dev/work/trunk> bzr slog -l 3
873: Coder 2011-01-19 * Applied some patch
872: GK 2011-01-19 [merge] Merged release
871: Gk 2011-01-19 [merge] Merged release

piranha@gto ~/dev/work/trunk> bzr slog -l 3 -n0
873: Coder 2011-01-19 * Applied some patch
1776: GK 2011-01-19 [merge] Merged release
  1644.81.11: GK 2011-01-19 [merge] Merged old release

Ветки

Бранчи. Если вы это читаете и пользовались только subversion’ом, то написанное здесь может и не быть понятно. Но если попользоваться меркуриалом или гитом, можно обратить внимание, что ветка - это просто набор изменений. Скажем, в гите понятие несколько перегружено тем, что там ветка - это что-то сто процентов именованное, но всë равно - в одном репозитории может быть несколько развитий истории (в том числе и безымянных) и никого это не беспокоит. То же самое в меркуриале - история плодит ветки и объединяет их. Это, в принципе, один из главных моментов в DVCS.

Базар выше всего этого. У него ветка - это отдельный репозиторий.

piranha@gto ~> bzr help branch | grep Aliases
Aliases:  get, clone

Это - одна из самых феерических жоп. Как только нужно сделать какое-то изменение, которое ответвляется от текущего, нужно клонировать репозиторий. Супер, это то, о чëм мечтали большевики! Естественно, это куда медленнее, чем работа с меркуриалом, постоянно надо перенастраивать разные эклипсы, TAGS-файл постоянно регенерировать, и заниматься прочими нужными и полезными делами.

Я не знаю, кто был архитектором базара, и знать не хочу, но то, что он был альтернативно мыслящим - это точно.

idiotic merge

А что у нас вытекает из того, что внутрирепозиторийных веток нет? А то, что bzr pull скажет - упс, наши бранчи (aka репозитории) разошлись, а сделай-ка ты merge. И ничего не скачает, конечно, разошедшихся веток-то быть в одном репозитории не может. Ну ок, я понимаю. Но что ты будешь мержить, ничего же не скачано? Ладно, смотрим. bzr merge. Ого! merge качает изменения! Неожиданный ход.

Объяснимо, конечно - куда деваться при такой архитектуре?

API

Я написал для базара хук. Не очень сложный, просто на коммите стрипает висящие пробелы у всех изменëнных файлов. Естественно, что я потратил кучу времени: у базара есть документация, которая, во-первых, убога, а во-вторых, устарела. Еще у него для написания хука нужно писать модуль на питоне (шелловый скрипт? Что вы, гордость не позволяет). Еще сам API просто убог на всю голову. Ужасен. Кошмарен. Код Базара не выдерживает никакой критики. Это реимплементация джавы на питоне. Феерический отстой.

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

Можно писать целую книгу “Bazaar: how not to write in Python”.

Форматы репозиториев

Ах, триста раз обсосанная тема. Конечно, нет никаких проблем в том, что изменился формат репозитория, ведь всегда можно сделать bzr upgrade. Вот только на сервере какая-то версия постарше, а формат еще старше, и мы пока не обновляем, потому что… и так всë работает. И тормозит, пля.

Изменение формата - это проблема для пользователя. А вы, господа разработчики, бестолковые животные, что смогли придумать вменяемый формат лишь с 15-го раза.

Кстати, кто гарантирует, что это последний?

Обмен патчами

Плавно перейдëм от архитектурных проблем к чисто интерфейсным. Такой вещи, как hg export или git format-patch - нет. Можно отправить патч с помощью bzr send, но он будет бинарный. Не знаю, как выразить свои эмоции. :( За последние несколько лет я так привык обмениваться с людьми текстовыми патчами, которые можно тут же почитать, откомментировать, так что тут меня это просто убивает. :( Разработка меркуриала вон полностью построена на этих патчах…

Фичи

Не хватает кучи фич по сравнению с лидерами. Например, посмотреть список изменений, сделанных каким-то человеком, невозможно (а-ля hg log -u или git log --author). И так далее - нет смысла всë перечислять, просто регулярно бьëшься головой “и этого тоже нет”. :(

Разная красота

Никакой тебе автопаджинации, никакой раскраски вывода. Никакого аналога hg serve, естественно, и вообще расширений толковых мало - потому что писать их очень напряжно. Пару лет назад я решил сделать расширение (для хг), чтоб смотреть диффстат изменений (окончилось это просто патчем и давно находится в самом меркуриале) и вместо написания с нуля решил переписать базаровское существующее. Я конечно постарался, но не в последнюю очередь благодаря приятному API базара моë расширение для меркуриала вышло в 2,5 раза короче.

Тхе енд

Естественно, это личное (ну, почти) дело каждого (каждой команды) - выбор системы контроля версий. И я не хотел никого обидеть - что, естественно, не получилось, потому что базар у меня вызывает откровенное отвращение и я был бы счастлив, если б он исчез с лица планеты.

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

Еще на почитать

If you like what you read — subscribe to my Twitter, I always post links to new posts there. Or, in case you're an old school person longing for an ancient technology, put a link to my RSS feed in your feed reader (it's actually Atom feed, but who cares).

Other recent posts

Server-Sent Events, but with POST
ngrok for the wicked, or expose your ports comfortably
PostgreSQL collation
History Snapshotting in TwinSpark
Code streaming: hundred ounces of nuances