Git-flow — это методология ветвления и слияния, сильно популяризированная заметкой 2010 года под названием «A Successful Git branching model» (была переведена на хабре как «Удачная модель ветвления для Git» — прим. перев.).
За последние десять лет бесчисленное множество команд пали жертвой этого громкого названия и оказались — не побоюсь этого слова — откровенно облапошены. В своей заметке автор утверждает, что они успешно внедрили эту модель в проекты, но умышленно не раскрывает подробности проектов, которые привели к этой «успешности».
И это главная ошибка тех, кто верит данной публикации. Общеизвестен факт, что не все стратегии работают во всех ситуациях, со всеми людьми, во всех контекстах. И я утверждаю, что та же логика применима и к этой модели ветвления.
На этом можно заканчивать, так? Ну, не совсем. Наверняка некоторые из вас скептически отнеслись к моей цепочке рассуждений, поэтому давайте копнем поглубже и попытаемся понять, почему модель ветвления Git-flow должна поджариться на медленном огне.
Git-flow изначально сложна и запутана
Модель Git-flow сложна даже в том случае, если на минуту забыть о микросервисах и непрерывной доставке (continuous delivery, CD). Посмотрите-ка на эту схему и рискните сказать, что она интуитивно понятна:
(источник)
Итак, мы имеем ветви функциональностей (feature), ветви релизов, master, develop, ветви исправлений (hotfix) и теги git. За всеми этими элементами необходимо следить, держать их в уме, учитывать в процессе сборки и выпуска.
Кроме того, нужно постоянно заострять внимание на том, что это за ветка и для чего она предназначена. Ментальная модель, которая требуется для реализации этого подхода, несет в себе высокую когнитивную нагрузку. Я пользуюсь git'ом уже 10 лет, но до сих пор не уверен, что смогу удержать в уме все нюансы происходящего.
Git-flow нарушает правило «короткоживущих» ветвей
В git'е число merge-конфликтов в ветке растет пропорционально числу людей, делающих коммиты в эту ветку. В случае Git-flow это число растет еще быстрее, потому что есть три других ветки (с разной продолжительностью жизни), которые сливаются в develop: ветви функциональностей, релизов и исправлений. Таким образом, потенциальное количество merge-конфликтов теперь минимум в три раза выше.
Нет уж, спасибо!
Я не склонен утверждать, что переживания по поводу merge-конфликтов являются веской причиной отказаться от стратегии ветвления вроде Git-flow, однако потенциальную сложность, связанную с появлением всех этих ветвей, невозможно игнорировать. Такой подход подошел бы для организации с низкой частотой коммитов, но для любой динамично развивающейся компании или стартапа он не пригоден.
С Git-flow придется забыть о rebase'ах
Признаю, что перебазирование — это многогранный вопрос, однако он важен для целей моего повествования. Сторонникам Git-flow придется отказаться от перебазирования: ведь оно происходит вместе со слиянием, в результате которого две ветви объединяются. А учитывая проблемы Git-flow с наглядностью, вам будет необходим способ визуально отслеживать ветви. Чтобы этим не заниматься, придется навсегда забыть о rebase.
Git-flow сильно усложняет непрерывную поставку
Continuous delivery — это практика, при которой разработчики выпускают обновления непосредственно в production (на самом деле, путем слияний с мастером) в автоматическом режиме. А теперь посмотрите на бардак, который творится в Git-flow, и объясните мне, как вы собираетесь проводить непрерывную доставку всего этого?
Вся модель ветвления основана на предсказуемом, долгосрочном цикле релиза новых версий, а не на выпуске нового кода каждые несколько минут или часов. Реализовать это слишком сложно, не говоря уже о принятой в CD практике накатывать исправления «на месте», в то время как Git-flow рассматривает исправления как отдельную сущность, которую необходимо бережно хранить, контролировать ее, держа отдельно от остальной работы.
В Git-flow невозможно работать с несколькими репозиториями
С появлением микросервисов начала набирать популярность и идея микрорепозиториев («Они ортогональны друг другу», — кричит мне суфлер). В ней отдельные команды контролируют свои репозитории и рабочие процессы, а также следят за тем, кто публикует код в их репозитории и как функционируют их workflows.
Вы когда-нибудь пробовали воспользоваться сложной моделью ветвления вроде Git-flow в условиях совместной работы нескольких команд? Получилось ли у вас добиться согласованности их действий? Сомневаюсь. Очень скоро система превращается в манифест различных ревизий разных репозиториев, и единственные, кто знают, где все лежит — это люди, которые пишут YAML-файлы для обновления манифестов. Если не соблюдать должную осторожность, то вопрос «Что у нас в production?» становится экзистенциальным.
Git-flow также не приспособлен для работы с единственным репозиторием
Если микрорепозитории не подходят из-за сложности с координацией релизов, почему бы не реализовать единый глобальный процесс ветвления, который все микросервисные команды будут использовать для релизов?
Увы, он просуществует всего несколько секунд — ровно столько, сколько требуется команде, чтобы сказать: «Это необходимо выпустить прямо сейчас» (хотя остальные команды вовсе не готовы к выпуску своих продуктов). В случае, когда команды работают независимо друг от друга, микросервисы также развертываются независимо, невозможно привязать рабочий процесс к централизованной модели ветвления, организованной в монорепе.
Кому подходит (и не подходит) Git-flow?
Если ваша компания придерживается месячного или квартального цикла выпуска ПО, а команда параллельно работает над несколькими релизами, то Git-flow может стать неплохим выбором. Для стартапа, сайта или веб-приложения со множеством релизов каждый день Git-flow не подходит. Если команда разработчиков невелика (менее 10 человек), то Git-flow вносит в ее работу слишком много церемоний и лишних движений.
С другой стороны, если команда насчитывает 20+ человек, работающих над параллельными релизами, то Gitflow обеспечивает достаточную структурированность, помогающую избежать путаницы.
Окей, моей команде Git-flow не подходит. Что нам использовать?
Я не могу ответить на этот вопрос. Каждая модель ветвления подходит для соответствующих команд, культур и условий. Сторонникам CD подходит модель, максимально упрощающая процесс. Кто-то обожает разработку на основе trunk'ов (trunk-based development) и переключатели функциональности (feature flags). Однако эти подходы до чертиков пугают меня сложностью тестирования.
Основная идея в том, чтобы подробно обсудить эту проблему со своей командой. Задайте ей следующие вопросы:
- Какие проблемы данная модель ветвления поможет нам решить?
- Какие проблемы она создаст?
- Какие подходы к разработке она стимулирует?
- Хотим ли мы этого?
Любая модель ветвления в конечном итоге предназначена для того, чтобы разработчикам было легче сообща работать над программным обеспечением, поэтому она должна учитывать потребности конкретных людей, которые будут ее использовать. Не стоит выбирать некую модель, основываясь лишь на том, что кто-то написал ей оду в интернете.
В заключение хочу сказать, что изначально намеревался использовать в названии устойчивое выражение «considered harmful», столь привычное для публикаций подобного рода. Однако поиск в google показал, что кто-то уже использовал его для своей статьи о вредности Gitflow. Рекомендую ее почитать.
Бонус. Ответ nvie (Vincent Driessen)
На следующий день после этой публикации автор оригинала «A Successful Git branching model» (Vincent Driessen), на которую ссылается George Stocker, разместил ответ:
Несколько соображений (5 марта 2020)Эта модель родилась в 2010 году — более 10 лет назад — практически сразу после того, как появился Git. За эти 10 лет Git-flow (модель ветвления, описанная в оригинальной статье) приобрела настолько высокую популярность у разработчиков, что ее начали рассматривать как своего рода стандарт — но, к сожалению, и как некую догму или панацею.
За эти 10 лет сам Git покорил весь мир, а наиболее распространенный тип программного обеспечения, разрабатываемого с помощью Git, все сильнее смещается в сторону веб-приложений — по крайней мере, таковы мои наблюдения. Как правило, веб-приложения разрабатываются в рамках подхода CD, не откатываются и не требуют поддержки нескольких одновременно запущенных версий ПО.
Это вовсе не тот класс ПО, который я имел в виду, когда писал свою статью десять лет назад. Командам, занимающимся непрерывной доставкой ПО, я бы рекомендовал использовать гораздо более простой рабочий процесс (вроде GitHub flow) вместо того, чтобы пытаться интегрировать Git-flow в свою работу.
В свою очередь, Git-flow может подойти командам, которые разрабатывают ПО с жестким версионированием или занимаются поддержкой нескольких версий приложения параллельно (Git-flow неплохо себя зарекомендовал на этом поприще за последние 10 лет). В этом случае рекомендую обратиться к оригинальной статье.
В заключение хочу напомнить вам, что панацеи не существует. Учитывайте свои условия, контекст и думайте своей головой!
P.S. Больше мнений по этой теме, конечно, можно найти на Hacker News и Reddit.
P.P.S. от переводчика
Читайте также в нашем блоге:
Комментариев нет:
Отправить комментарий