Ноя 10, 2015 - 0 Comments - Без рубрики -

Mercurial vs. Git в коммерческой разработке

Для начала я хочу внести ясность в понятие коммерческой разработки и её отличий от других моделей. В коммерческой разработке принято ставить конкретные цели и отслеживать этапы выполнения работы. Тогда как, например, в open source моделях разработки, обычно цели ставит перед собой отдельный разработчик, а этапность их исполнения и привязка к бизнес требованиям никого не интересует.

Зачем вообще нужна система контроля версий? Есть несколько причин:
— Обеспечить одновременную возможность работы коллектива над кодом;
— Сохранить лог всех изменений и версий для того чтобы при необходимости вернуть версию или часть кода, а также разобраться в проблеме на основе анализа изменений.

Отличия между Git и Mercurial

Главное отличие — «Its all in branches», как сформулировал однажды Felipe Contreras в своём блоге. В статье приведена масса аргументов, почему git технически лучше, чем mercurial, и большинство из этих аргументов бесспорны. Действительно, для программиста проекта open source на сегодняшний день git — лучший выбор.

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

Но этот выбор может оказаться сомнительным, если взглянуть на него с точки зрения PM. А вот многие слабые места Mercurial оказываются, на поверку, его сильными сторонами.

Взгляд техлида/PM — почему Mercurial удобнее

Предлагаю рассмотреть следующие отличия git vs. mercurial в контексте их удобства для PM и коммерческого проекта в целом:
— невозможность удаления веток, коммитов, т.е. изменения истории репозитория;
— уровень сложности обучения;
— «тяжёлые» ветки, в коммитах которых ветка привязана напрямую.

Отслеживаемость изменений

На всех наших проектах поддержка Traceability позволяет нам работать более эффективно. Если вернуться в начало статьи, то трассировка позволяет нам отслеживать:
— этапность изменений;
— привязку изменений к бизнес требованиям.

Как это реализовано на практике: связка с таском кодируется в названии ветки, например: 29277_pivot_table, 30249_summary_page, 30081_agroups, 28255_angularjs_todo. Мы работаем c теми самыми «тяжёлыми» ветками, в которых ветка привязана к коммиту. В номере ветки кодируется номер задачи и краткое описание. Потом, если вдруг в hg annotate (аналог команды blame) мы попытаемся понять, кто изменил конкретную строку кода, нам не составит труда открыть трекинговую систему с номером таска. В таске, в свою очередь, перечислены (путём обычных comments) список всех изменений к данному таску.

И если вдруг заказчик задаст мне вопрос: «Кто выпилил важный баннер на первой странице с рекламой главного рекламодателя?» — я смогу чётко ответить, указав ссылку на бизнес требование и таск, с ним связанный.

Полноценная трассировка невозможна в Git по нескольким причинам:

— Ветка может быть удалена. Git, как более мощный инструмент, позволяет удалять ветки и другие части лога из истории. То есть вполне может так оказаться, что останется только merge commit, в котором может быть указана только общая причина (например, «вливка версии 11 в master»).

— Возможно, вы обнаружите commit девелопера, но это ещё не решение. В коммите может быть сказано: «Выпилил баннер». А почему так произошло — тайна покрытая мраком. Тут приходится делать упор на то, чтобы девелоперы обязательно ставили номер таска в commit msg. Регулярно наблюдаю эту картинку в командах, которые работают с git, и там же регулярно наблюдаю процентов 40-60% коммитов без метки таска.

Для того, чтобы хоть как-то решить эту проблему, в Jira стоит авто-отслеживание коммитов по номеру таска, совпадающих с названием проекта. Но этого оказывается недостаточно для 100% гарантии результата.

Сложность обучения и эксплуатации

Большинство людей, которые используют git, вообще не понимают, о чём я говорю. Ну да, они «уже» работают, в 90% случаев не вдаваясь в подробности, почему это так устроено. Некоторые имеют на бумажке «шпаргалку» в которой указаны наиболее часто используемые команды.

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

1. Разделение типов репозиториев в git и команда clone

Начнём с первого шага, и здесь я сразу вижу некоторую неудобность git в рельной жизни. И в git, и в mercurial синтаксис команды clone одинаковый:

git clone <откуда> <куда>
hg clone <откуда> <куда>

Вроде всё логично? Всё, да не совсем. В Git, оказывается, есть разделение репозиториев на клоны для девелоперов (рабочие) и клоны для сервера (bare). Это сделано, видимо, в целях оптимизации, но в результате, чтобы обменяться кодом с соседом программистом, мне уже недостаточно будет просто написать hg push ssh://otheruser@othercomp, а потребуется создать bare репозиторий и организовать обмен кодом на его основе.

2. Работа с ветками

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

В коммерческой же модели разработки PM’у важно видеть объём и качество сделанной работы каждый день, а иногда и чаще. И, соответственно,удобно, чтобы все рабочие ветки заливались на сервер, что по умолчанию происходит в mercurial.

Я не хочу сказать, что работа с локальными/удалёнными ветками — это плохо. Опционально я был бы не против такой фичи в mercurial. Но её полезность в нашей ежедневной работе под большим сомнением.

Помимо того, данный функционал довольно сильно усложняет синтаксис вызова команд. Если в Mercurial всё, что вам требуется знать, — это просто команды создания, перехода между ветками, то в git всё намного сложнее. И хотя сложный функционал востребован редко, пользоваться им приходится всем. Примеры для сравнения:

hg git комментарий
hg diff git diff HEAD показать текущие изменения
hg up branchname git checkout -b branchname origin/branchname перейти в ветку
hg push git push
git push origin master
отправить изменения на сервер

Мне поначалу было сложно понять, что за origin и почему надо указывать ветку.

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

Будьте внимательны с синтаксисом вызова git. Допустим, для удаления ветки в git используется не очень понятная конструкция типа git push origin :the_remote_branch. То есть мы отправляем «пусто» заменить ветку на сервере — в результате команды удаляется ветка на сервере.

С точки зрения менеджмента это опасная команда. Я бы такую запретил, если бы мог:) Или, как вариант, — бекапировать основной репозиторий время от времени.

В Mercurial ничего удалить нельзя (тривиальным способом). Для меня как для PM’а это плюс, для разработчика скорее минус.

Простота запоминания команд в Mercurial

Сравните:

hg git
hg in git fetch && git log master..FETCH_HEAD
hg out git fetch && git log FETCH_HEAD..master
hg purge git clean -fd
hg revert -a git reset --hard
hg addremove git add .; git ls-files --deleted xargs git rm
hg glog git log --graph --all --decorate

Ну и закодированное git config по сравнению с обычным простым файлом .hg/hgrc

Минусы Mercurial

Все вышеуказанные плюсы в какой-то мере могут стать и минусами. Например, самая проблемная ситуация — не стоит добавлять огромные файлы в репозиторий. Один наш заказчик решил, что таким образом можно добавить media файлы, включая рекламные ролики, и размер репозитория резко вырос на размер видео, помноженный на два. Удалить их простым способом было невозможно, пришлось использовать ConvertExtension.

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

Третий минус — вы, как PM, скорее всего, не сможете переубедить свои программистов в необходимости перехода на Mercurial. Причина проста — они уже выучили один синтаксис, переучиваться не хотят. Тем более, на заведомо более слабую по фичам систему. Есть шанс, если стартовать новый проект.

Выводы

Спор о том, что лучше, а что хуже, сильно зависит от контекста решаемых задач. Мой выбор на сегодня прост — для Open Source я пользуюсь в основном git, в коммерческих проектах — только Mercurial.

Хочу пожелать читателям правильно делать свой выбор.


Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *