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