Практически все современные системы контроля версий поддерживают ветки — независимые направления работы, берущие начало от одной центральной базы кода. В зависимости от того, какую систему контроля версий вы используете, основная ветка может называться главной веткой, веткой по умолчанию или стволом. Разработчики могут создавать собственные ветки, отходящие от главной ветки кода, и работать над ними параллельно с ней.
Зачем нужны ветки?
Ветки позволяют командам разработчиков без труда вести совместную работу с одной централизованной базой кода. Когда разработчик создает ветку, система контроля версий создает копию базы кода, актуальную на текущий момент времени. Изменения ветки не влияют на работу других разработчиков в команде. Это, конечно же, хорошо, потому что разработка функциональных возможностей сопряжена с постоянными изменениями, и если бы вся работа велась в главной ветке, процесс разработки погрузился бы в хаос. Но ветки не должны существовать в полной изоляции. Разработчики могут без труда запрашивать изменения у других разработчиков, чтобы вместе работать над функциональностью и не допускать слишком сильного отклонения их собственной ветки от главной.
Ветки нужны не только для работы над новыми функциями. Они могут оградить команду от влияния значительных архитектурных изменений, например обновления платформ, общих библиотек и т. д.
Три стратегии ветвления для agile-команд
Обычно каждая команда пользуется своей моделью ветвления. В сообществе разработчиков часто спорят о том, какой подход наиболее эффективен. Камнем преткновения в большинстве случаев является объем работы, который должен находиться в ветке перед ее слиянием с главной веткой.
Использование веток релизов
Эта стратегия предполагает, что весь релиз помещается в одну ветку. Согласно ей, на поздних этапах цикла разработки менеджер по релизам создает новую ветку, отходящую от главной (например, «ветка разработки версии 1.1»). Все изменения версии 1.1 нужно применить дважды: к ветке 1.1 и затем к основной базе кода. С появлением второй ветки у команды появляется дополнительная работа. К тому же легко забыть о необходимости выполнять слияние. В некоторых случаях в ветках релизов сложно разобраться и ими сложно управлять, поскольку над одной и той же веткой работает сразу много людей. Вы наверняка проходили через мучения, которые вызывает необходимость объединять множество различных изменений в одной ветке. Если вам нужна ветка релиза, создавайте ее как можно ближе к дате фактического выпуска новой версии.
Ветки релизов играют важную роль для поддержки ПО, представленного на рынке сразу несколькими версиями. У одного продукта может быть несколько веток релизов (например, 1.1, 1.2, 2.0), на базе которых ведется длительная разработка. Помните, что изменения в более ранних версиях (таких как 1.1), возможно, понадобится объединить с ветками более поздних релизов (таких как 1.2, 2.0). Подробнее об управлении ветками релизов с помощью Git можно узнать из вебинара, запись которого приведена ниже.
Использование функциональных веток
Часто функциональные ветки снабжаются флагами возможностей — «переключателями», с помощью которых можно включить или отключить возможность в составе продукта. Благодаря этому проще развертывать код в главной ветке и выбирать, когда активировать новую возможность. В итоге первоначальное развертывание кода может произойти задолго до демонстрации возможности конечным пользователям.
Использовать флаги возможностей полезно и потому, что код остается в сборке, но не активен, пока идет разработка. Если при активации возникнут проблемы, флаг возможности позволяет системному администратору выключить ее и вернуться к заведомо исправному состоянию, вместо того чтобы развертывать новую сборку.
Использование веток заданий
В компании Atlassian преимущественно используют модель, согласно которой для каждого задания создается по ветке. В каждой организации принято по-своему делить объем работы на отдельные задания. Это делается в системе управления задачами, такой как Jira Software. Задачи становятся главными точками соприкосновения с тем или иным заданием для команды. При использовании веток заданий (задач) устанавливается прямая связь между задачами и исходным кодом. Каждая задача выполняется в отдельной ветке, и к названию этой ветки добавляется ключ соответствующей задачи. По ключу задачи в названии ветки легко понять, к какой задаче относится тот или иной участок кода. Такая прозрачность позволяет без труда применять отдельные изменения к главной ветке или любой ветке релиза, которая уже давно находится в работе.
Принципы Agile вращаются вокруг пользовательских историй, поэтому ветки заданий идеально вписываются в процесс гибкой разработки. Для каждой пользовательской истории (или исправления бага) выделяется собственная ветка, и благодаря этому несложно понять, какие задачи еще выполняются, а какие уже готовы к релизу.
А теперь познакомимся со злым братом-близнецом ветвления — слиянием
Всем нам довелось пройти через испытание по объединению нескольких веток в одно вразумительное решение. Из-за таких централизованных систем управления версиями, как Subversion, сложился стереотип о слиянии как о чем-то невероятно мучительном. Однако более новые системы управления версиями, такие как Git и Mercurial, предлагают другой подход к отслеживанию версий файлов, содержащихся в разных ветках.
Работа над ветками в большинстве случаев ведется недолго, из-за чего проще выполнять их слияние и управлять ими в разных участках базы кода. С одной стороны, непрерывная интеграция (CI) позволяет объединять ветки часто и автоматически; с другой стороны, ветки, которые меньшее время находятся в работе, попросту содержат меньше изменений. Благодаря этому для команд, использующих Git и Mercurial, «муки слияния» канули в лету.
Вот почему использовать ветки заданий так круто!
Проверка, проверка и еще раз проверка
Возможности системы управления версиями ограничиваются влиянием на исход слияния. Большое значение имеют автоматическое тестирование и непрерывная интеграция. Большинство серверов CI могут автоматически подвергать новые ветки тестам, благодаря чему вероятность столкнуться с ошибками при заключительном слиянии с вышестоящей веткой значительно снижается, и главная ветка кода остается стабильной.