Рабочий процесс Gitflow Workflow
Git-flow — это устаревшая версия рабочего процесса Git, в свое время ставшая принципиально новой стратегией управления ветками в Git. Популярность Git-flow стала снижаться под влиянием магистральных рабочих процессов, которые на сегодня считаются предпочтительными для современных схем непрерывной разработки ПО и применения DevOps. Кроме того, Git-flow не слишком удобно применять в процессах CI/CD. В этой публикации приводится описание Git-flow для истории.
Что собой представляет Git-flow?
Git-flow — альтернативная модель ветвления Git, в которой используются функциональные ветки и несколько основных веток. Эта модель была впервые опубликована и популяризована Винсентом Дриссеном на сайте nvie. По сравнению с моделью магистральной разработки, в Git-flow используется больше веток, каждая из которых существует дольше, а коммиты обычно крупнее. В соответствии с этой моделью разработчики создают функциональную ветку и откладывают ее слияние с главной магистральной веткой до завершения работы над функцией. Такие долгосрочные функциональные ветки требуют тесного взаимодействия разработчиков при слиянии и создают повышенный риск отклонения от магистральной ветки. В них также могут присутствовать конфликтующие обновления.
Git-flow можно использовать для проектов, в которых запланирован цикл релизов и реализуется характерная для DevOps методика непрерывной поставки. В этом рабочем процессе используются понятия и команды, которые были предложены в рамках рабочего процесса с функциональными ветками. Однако Git-flow привносит новые специфические роли для разных веток и определяет характер и частоту взаимодействия между ними. Помимо функциональных веток в рамках этого рабочего процесса используются отдельные ветки для подготовки, поддержки и регистрации релизов. При этом вы по-прежнему можете пользоваться преимуществами рабочего процесса с функциональными ветками, такими как запросы pull, изолированные эксперименты и эффективное командное взаимодействие.
User Flow — что это и как создать? Примеры

Успешность любого IT проекта определяется не его дизайном, функционалом или быстродействием, а тем получает ли пользователь решение своей задачи. User Flow помогает понять и оптимизировать путь пользователя для получения решения. Разберем тему подробнее, поймем для чего нужен User Flow и как его составить.

Визуальное представление пользовательского сценария позволяет оценивать и оптимизировать пользовательский опыт (UX), уменьшать количество шагов для выполнения задачи и повышать конверсию достижения той или иной цели.
Итог каждого User Flow — достижение конкретной цели. Схема помогает понять, насколько логично и корректно завершаются процессы, например: поиск, создание учетной записи, покупка, скачивание или загрузка.
Каждый элемент блок-схемы в User Flow имеет свою форму и каждая форма означает определенный процесс:

- Круг — начало / конец. Используется для указания начала и конца пользовательского сценария;
- Ромб — принятие решения. Ромб указывает на моменты принятия решения, где у пользователя есть выбор (например: да/нет, зарегистрироваться/без регистрации и т. д.), в зависимости от решения пользователя определяется следующий шаг;
- Прямоугольник— действие. Прямоугольники указывают на действия, которые пользователь должен выполнить, например войти, открыть корзину, отправить сообщение;
- Стрелка / узел — направление. Стрелки указывают направление пользователя от шага к шагу. Стрелки могут переходить последовательно от одного шага к другому, перескакивать шаги или возвращать назад на основе пользовательских решений.
Шаблоны User Flow
Подготовил для вас 6 шаблонов User Flow с реальных проектов на русском языке в Figma (FigJam) с возможностью копирования и редактирования:
- Интернет магазин
- Доска объявлений
- Новостной сайт / блог
- Сервис услуг
- Приложение доставки
- Календарь мероприятий
Зачем нужен User Flow
Изучение пользовательского сценария сайта или мобильного приложения будет полезным независимо от того разрабатывается новый продукт или дорабатывается старый и вот почему:
1. Помогает создать удобный интерфейс
Уже на стадии блок-схем команда видит, как тот или иной сценарий приводит к цели пользователя или наоборот путает его. Разработчики оценивают эффективность создаваемого интерфейса с точки зрения простоты и удобства передвижения по продукту. Важным аспектом является то, что User Flow заставляет дизайнера и команду разработчиков разрабатывать интерфейс продукта с точки зрения пользователя. Все это приводит к более интуитивно понятному продукту, который удовлетворяет клиентов.
2. Помогает улучшить существующие интерфейсы
Пользовательский сценарий позволяет оценить, как пользователи перемещаются по существующему интерфейсу, выстроить воронку и замерять конверсию на каждом из шагов. Это позволит сформировать гипотезы где и почему происходит просадка и что нужно сделать чтобы это исправить. Например: уменьшить или увеличить количество информации на странице, изменить количество полей на формах, изменить навигацию, сократить количество шагов и т.д. И уже на базе гипотез проводить A/B тесты и вносить изменения в сценарий.
3. Продемонстрировать структуру проекта
User Flow дает представление о продукте в наиболее простой и эффективной форме. Можно использовать в презентации проекта команде, партнерам, инвесторам, как дополнительный способ объяснения пользы продукта для пользователя и пути по которому, пользователь будет взаимодействовать.
4. Ускорить дальнейшую разработку
Когда разработчики начнут создание, визуальное отображение пути пользователя поможет в понимании проекта и ускорит дальнейшее проектирование и разработку, а также снизит вероятность переделок и доработок.
Как создать User Flow
1. Исследовать пользователей
Перед началом создания User Flow нужно знать своих клиентов. Для этого проводятся исследования, которые дают понимание откуда будут приходить клиенты, какие у них цели и задачи, какую услугу и сервис они хотят и т.д. Все это нужно для того, чтобы знать какие действия будут предпринимать пользователи, чтобы посетить сайт и как будут использовать сам продукт. Если это понимание уже есть, то можно переходить к следующему шагу.
2. Расписать цели и пути достижения
Сформировать цели и шаги по достижению данных целей. Простой пример:
Цель купить товар в интернет магазине, соответственно шаги: вход на сайт — переход в каталог — переход в карточку товара — добавление в корзину — переход в корзину — оформление заказа — оплата — выход.
Определив конечные цели для User Flow можно подстраивать путь под цели для создания лучшего пользовательского опыта, убирать или добавлять шаги, условия.
3. Визуализация целей и путей в User Flow
Закончив 1 и 2 шаг, можно приступить к проектированию User Flow. Для одной большой цели создается одна блок-схему, если целей несколько, то создаются несколько схем с названиями конкретной цели (например: регистрация на сайте, покупка товара, написание отзыва).
Когда создавать User Flow
User Flow необходимо создавать на самой ранней стадии разработки проекта, сразу после того, как вы определись с идеей и провели исследование рынка и пользователей. Очень важно разработать пользовательские сценарии до начала работ по прототипированию и дизайну интерфейсов. Иначе высок риск создать проблемные области, лишние шаги и экраны, которые будут только усложнять путь пользователя.
Инструменты для создания User Flow
Ввиду того, что как инструмент User Flow достаточно простой в создании, выбор инструмента не является критичным вопросом. User Flow можно составить хоть на бумаге, доске. Но для удобства редактирования и доступа, лучше все же пользовать специализированными программами. К счастью их огромное множество.
Я предпочитаю FigJam, это внутренний инструмент Figma. Мне нравится работать сразу в одном окне и с User Flow и с прототипом. Стоит еще упомянуть такие решения как: Overflow, Axure, XMind, Miro. По ним есть куча туториалов, по которым можно быстро понять как работать в той или иной программе.
Примеры User Flow
Вот пример простого пользовательского сценария нашего проекта UNICORN BASE.
Цель клиента: Получить доступ к базе контактов. Путь состоит из следующих шагов:
- Вход на сайт;
- Подбор в каталоге (фильтрация);
- Выбор карточки;
- Проверка авторизации;
- Регистрация;
- Проверка доступа к контактам;
- Описание тарифа;
- Оплата тарифа;
- Выдача доступа;
- Полный доступ к каталогу

Итог
Начиная создание нового проекта с момента идеи и исследования клиента, но еще до момента начала разработки прототипа и дизайн макетов, важно создать пользовательский путь. User Flow является основой для требований к структуре и контенту проекта, логики переходов между страницами и окнами. Понимая потребности пользователей, команде гораздо вероятнее сделать успешный продукт, который будет удовлетворять этих самых пользователей.
Если вы хотите создать пользовательский путь самостоятельно, следуйте этому руководству и пробуйте. Так же я могу помочь вам с разработкой User Flow в рамках услуги прототипирование.
Подготовил для вас 6 шаблонов User Flow с реальных проектов на русском языке в Figma (FigJam) с возможностью копирования и редактирования:
- Интернет магазин
- Доска объявлений
- Новостной сайт / блог
- Сервис услуг
- Приложение доставки
- Календарь мероприятий
GitLab Flow
Это перевод достаточно важной статьи про GitLab Flow, альтернативе Git flow и GitHub flow. Статья была написана в 2014, так что скриншоты успели устареть. Тем не менее сама статья более чем актуальна:
Ветвление и слияние веток в git устроено гораздо проще, чем в более ранних системах контроля версий, таких как SVN. Поэтому есть много способов организации командной работы над кодом, и большинство из них достаточно хороши. По крайней мере, они дают много преимуществ по сравнению с тем, что было до git. Но сам по себе git — не серебряная пуля, и во многих командах организация рабочего процесса с git имеет ряд проблем:
- Не описан точным образом весь рабочий процесс,
- Вносится ненужная сложность,
- Нет связи с трекером задач (issue tracker).
Мы хотим представить вам GitLab flow — чётко определённый набор практик, решающий эти проблемы. Он объединяет в одну систему:
- Практику разработки, управляемой функциональностью (feature driven development),
- Использование feature-веток (feature branches),
- Трекер задач.
Эта статья описывает все аспекты GitLab flow, включая работу с ветками, интеграцию с задачами, непрерывную интеграцию и развёртывание. Её цель — помочь новым командам перейти на git и сразу внедрить простые, прозрачные и эффективные правила работы с ним.

В большинстве систем контроля версий, чтобы поделиться кодом с коллегами, нужно сделать одно действие — коммит в репозиторий. В git то же самое происходит в три этапа:
- Добавить изменения из рабочей области проекта в индекс (область подготовленных файлов, staging area);
- Сделать коммит на основе индекса;
- Запушить коммит в удалённый репозиторий.
Освоение этих действий — первый шаг в изучении git. Следом идет работа с ветками.

Если не устанавливать никаких правил работы с ветками, в репозитории начинает расти энтропия:
- Появляется много долгоживущих веток,
- Вносимые изменения оказываются размазанными по разным веткам,
- Непонятно, откуда начинать разработку новой фичи или откуда разворачивать код на production.
Для решения этих проблем обычно внедряется некая стандартная модель работы, например git flow или GitHub flow. Мы считаем, что у всех этих моделей есть потенциал для улучшения, поэтому мы разработали GitLab flow.
Git flow и его ограничения

Модель рабочего процесса Git flow появилась одной из первых и стала довольно широко известной. Она предполагает наличие основной ветки master , ветки для накопленных изменений develop , а также отдельных веток для фич, релизов и хотфиксов. Разрабатываемые изменения мержатся в develop , оттуда в релизные ветки, и в итоге попадают в master . Git flow достаточно подробно и четко определяет рабочий процесс, но его сложность порождает две проблемы.
Во-первых, разработчики должны использовать ветку develop , а не master , потому что последняя зарезервирована под релизный код. Это противоречит привычной практике называть master основную ветку, от которой ответвляются прочие ветки, и в которую мержится результат. Нередко разработчики по ошибке мержат какие-то изменения только в master , забывая про develop . А большинство графических интерфейсов к git по умолчанию считают основной веткой именно master , поэтому в них приходится каждый раз что-то переключать или настраивать.
Во-вторых, лишняя сложность появляется из-за веток релизов и хотфиксов. Большинство команд, особенно небольших, может легко обойтись без них. Сегодня большинство организаций придерживается практики непрерывной доставки (continuous delivery), которая предполагает, что код из основной ветки можно развёртывать на продакшен (production, то, что предоставляется пользователям).
Следовательно, можно исключить ветки релизов и хотфиксов и всю лишнюю работу, которая для них требуется. Пример такой лишней работы — обратный мерж релизных веток в master . Для решения этой проблемы есть специальные инструменты, но они тоже требуют изучения документации и только добавляют сложности.
GitHub flow – более простой вариант

В противовес сложной модели git flow был разработана модель GitHub flow. В ней есть только master и feature-ветки. Это упрощение привело к успешному внедрению GitHub flow множеством компаний. Компания Atlassian предложила похожую стратегию. Но, в отличие от GitHub, они предпочитают делать ребейз (rebase), а не мерж веток в master .
Мерж всех изменений в master и частое развёртывание позволяют не писать код «в стол», а сразу выпускать изменения. Это соответствует идеям бережливого (lean) производства и непрерывной доставки. Но множество вопросов остаются без ответа: когда именно нужно развёртывать и в каких окружениях, как выпускать релизы, как связать всё это с трекером задач. GitLab flow отвечает на все эти вопросы.
GitLab flow: ветка production

GitHub flow строится на предположении, что вы можете развернуть ваш код на продакшен в любой момент, сразу после мержа feature-ветки в master . Это верно для SaaS-приложений, но неверно в множестве других случаев. Бывает, что вы не можете влиять на точное время релиза. Например, вы выпускаете приложение под iOS и каждое обновление должно пройти валидацию в AppStore. Другой пример — когда релизить можно в строго определённое время (например, с 10 до 16 в будние дни, когда все сотрудники находятся на рабочем месте), но замержить ветку в master можно в любое время.
Для управления выпуском кода в продакшен GitLab flow предлагает использовать специальную ветку production . Настройте автоматическое развёртывание кода из этой ветки при каждом изменении в ней. Теперь для релиза достаточно сделать мерж из ветки master в production . Состояние ветки даст вам точную информацию о том, какая версия кода сейчас выпущена, а приблизительное время выпуска можно будет определить по времени создания мерж-коммита. Если вам нужна абсолютная точность, можно в процессе развёртывания создавать новый тег с timestamp’ом в описании.
GitLab flow: ветки для нескольких сред

Может быть полезно иметь отдельную среду (environment), в которую происходит развёртывание из ветки master . В этом единственном случае название среды может отличаться от названия ветки.
Предположим, что у вас есть несколько сред: стейджинг (staging), пре-продакшен (pre-production) и продакшен (production). Код из master автоматически развёртывается на стейджинг. Как только вы готовы развернуть его на пре-продакшен, вы создаете мерж-реквест из master в pre-production . Соответственно, мерж из pre-production в production означает окончательный релиз. Такой процесс, когда все коммиты проходят через ветки в строго определенном порядке, гарантирует, что изменения прошли тестирование во всех средах.
Если вам нужно быстро «протащить» хотфикс на продакшен, то можно реализовать его в обычной feature-ветке, а потом открыть мерж-реквест в master , не удаляя ветку. Теперь, если код в master проходит тесты и жизнеспособен (правильно настроенная непрерывная доставка должна гарантировать это), вы можете замержить ветку хотфикса последовательно в pre-production и production . Если же изменения требуют дополнительного тестирования, то вместо немедленного мержа нужно открыть мерж-реквесты в те же ветки. В «экстремальном» случае отдельная среда может создаваться для каждой ветки. Так делается, например, в Teatro.
GitLab flow: релизные ветки

Ветки релизов понадобятся вам только если вы выпускаете ПО для внешних клиентов. В таком случае каждая минорная версия будет храниться в отдельной ветке ( 2.3-stable , 2.4-stable и т.п.).
Стабильные (stable) ветки должны создаваться от ветки master . Их нужно создавать как можно позже, чтобы минимизировать добавление хотфиксов в несколько веток. После того, как релизная ветка создана, в неё можно включать только исправления серьёзных багов. Следуйте правилу «upstream first»: всегда, когда это возможно, сначала делайте мерж исправлений в master , и только оттуда — cherry-pick в релизную ветку. Благодаря этому правилу вы не забудете сделать cherry-pick исправлений в master и не встретите тот же самый баг в следующем релизе. Правило «upstream first» применяется в том числе в Google и Red Hat. Каждый раз, когда в релизную ветку добавляется исправление бага, нужно повысить третье число в номере версии (по правилам семантического версионирования). Обозначьте эту версию новым тегом в git. В некоторых проектах используется ветка stable , которая всегда указывает на тот же коммит, что и последний релиз. Ветка production (или master в правилах git flow) в таком случае не нужна.
GitLab flow: мерж/пулл-реквесты

Мерж-реквест или пулл-реквест создаётся в системе управления git-репозиториями. Это запрос на мерж одной ветки в другую, подобно задаче, назначаемый на какого-либо исполнителя. GitHub и Bitbucket используют термин «пулл-реквевст», потому что первое необходимое действие — сделать пулл предлагаемой ветки. GitLab и Gitorious используют термин «мерж-реквест», потому что заключительное действие — собственно, мерж ветки. Далее в этой статье мы будем называть это мерж-реквестом.
Если вы работаете над веткой больше, чем пару часов, имеет смысл поделиться промежуточным результатом с коллегами через мерж-реквест. Не назначайте его на кого-либо, а просто упомяните (командой /cc @имя ) ваших коллег в описании реквеста или в комментарии — они получат уведомление. Это будет означать, что реквест не готов к мержу, но по нему уже можно давать обратную связь. Вы можете явным образом обозначить, что работа над реквестом не завершена. Для этого начните заголовок реквеста с [WIP] или WIP: , то есть «Work in progress». Такой мерж-реквест даже нельзя будет замержить через интерфейс GitLab (хотя по-прежнему можно вручную через git).
Интерфейс GitLab позволяет оставлять комментарии как к реквесту в целом, так и к конкретным строкам кода. Таким образом, мерж-реквест уже включает в себя инструментарий для ревью кода, и какие-то дополнительные инструменты вам не понадобятся. По результатам ревью кто угодно может внести правки следующим коммитом в ту же ветку (обычно это делает автор реквеста). Все последующие коммиты, запушенные в эту же ветку, включаются в мерж-реквест, а дифф обновляется автоматически и корректно работает даже с push -f .
Когда фича готова, и ветку можно мержить, назначьте реквест на того, кто хорошо знает код проекта (и у кого есть права на мерж в master ). Этот человек несёт ответственность за окончательное ревью и принимает решение: замержить результат или закрыть реквест без мержа.
В GitLab есть стандартная практика — «защищать» долгоживущие ветки (такие как master или production ). Защита ветки не позволяет участникам с уровнем доступа «Developer» пушить в неё любые изменения.
Поэтому для мержа в защищённую ветку нужно открывать мерж-реквест, назначаемый на участника с более высоким уровнем доступа.
GitLab flow: интеграция с задачами (issues)

GitLab flow позволяет вам явным образом связывать код и задачи из трекера.
Любые значимые изменения в коде должны сопровождаться задачей, в которой сформулированы требования и смысл изменений. Это помогает оставаться в рамках задачи, а также даёт команде представление о том, чем вы заняты. В GitLab каждое изменение кодовой базы начинается c оформления задачи в трекере. Если предполагаемые изменения хоть сколько-нибудь серьёзны (например, требуют более часа работы), то работу нужно начинать с оформления задачи. Многие команды уже следуют этому правилу, потому что всегда оценивают время выполнения задачи, прежде чем взять её в спринт.
Заголовки задач желательно формулировать так, чтобы они описывали желаемое состояние системы.
Хороший пример: «Как администратор, я хочу иметь возможность удалить пользователя без ошибок».
Плохой пример: «Админ не может удалять пользователей».
Приступая к работе над задачей, создайте новую ветку от ветки master . Её название должно начинаться с номера тикета, например 42-admin-can-remove-users .
Когда вы завершили работу над задачей или хотите получить промежуточную обратную связь, открывайте мерж-реквест. Помните о возможности отправить оповещение ( /cc @имя ) коллегам и отметке WIP: .
В момент, когда вы считаете, что работа завершена, назначьте реквест на ревьюера и уберите WIP: .
Ревьюер может принять (замержить) реквест как через командную строку, так и через кнопку в интерфейсе реквеста. Нажатие на кнопку автоматически создаёт мерж-коммит, описание которого формируется на основе описания реквеста. Мерж-коммит полезен тем, что он сохраняет в истории время и обстоятельства мержа. Поэтому, по умолчанию, коммит создаётся всегда, даже если был возможен «fast-forward merge», когда master просто переключается на последний коммит вашей ветки. В git эта стратегия называется «no fast-forward» и используется с командой git merge —no-ff . GitLab EE и .com предлагают выбор поведения при мерже, подробности далее в статье.
Feature-ветка обычно больше не нужна после мержа, поэтому интерфейс реквеста позволяет удалить её. Предположим, что ветка была замержена, после чего вы обнаружили какие-то недоработки и переоткрыли задачу. Если старая ветка удалена, можно создать новую ветку с тем же именем и продолжить разработку в ней. Как правило, одной задаче соответствует не более одной ветки, но в одной ветке может решаться несколько задач.
Связывание задач и мерж-реквестов

В сообщении коммита, либо в описании мерж-реквеста можно упомянуть задачу по её номеру, используя слово-триггер, например: fixes #14 , closes #67 . При этом GitLab публикует в упомянутой задаче комментарий с обратной ссылкой на коммит или реквест. А в мерж-реквесте появляется список связанных задач. Когда вы замержите код в основную ветку, связанные задачи будут отмечены как выполненные. Обратите внимание: триггеры распознаются только на английском, то есть fixes #14 сработает, а исправляет #14 — нет.
Если вы хотите создать ссылку на задачу, но не закрывать её, напишите просто её номер: «Duck typing is preferred. #12».
Если некоторая задача охватывает несколько репозиториев, лучше всего создать основную задачу в одном репозитории и привязать к ней отдельные задачи в других репозиториях.
Rebase и объединение коммитов

Git позволяет объединить (squash) несколько коммитов в один или поменять их порядок с помощью команды rebase -i . В GitLab EE и .com вы можете сделать это непосредственно перед мержем через веб-интерфейс. Это имеет смысл, если в процессе работы вы сделали несколько небольших коммитов, но хотите чтобы в master попал один, или если хотите выстроить коммиты в логическом порядке.
Помните, что коммиты, которые уже попали в удалённый репозиторий и, тем более, в стабильную ветку, ребейзить нельзя. Причина этого в том, что-нибудь мог оставить ссылку на них или вытащить (cherry-pick) в свою ветку. Ребейз меняет идентификаторы (SHA-1) коммитов, потому что фактически создаёт из них новые коммиты. В результате ваши изменения появляются в истории git с несколькими разными идентификаторами, что приводит к путанице и ошибкам. Ребейз также затрудняет ревью кода, так как теряется информация о том, какие изменения были внесены после ревью. Если объединяются коммиты разных авторов, то информация об авторстве тоже будет потеряна. Это лишает авторов указания на их авторство, а ещё мешает работе git blame (показывает, в каком коммите и кем изменялась каждая строка).
Регулярно делать коммиты и пушить их в удалённый репозиторий — хорошая практика, позволяющая коллегам видеть, над чем вы работаете. Но при таком подходе одна задача размазывается на много коммитов, так что историю разработки становится довольно сложно просматривать. Эти небольшие коммиты можно было бы объединить в один, но это приведёт к потере идентификаторов. Вместо этого можно просматривать историю по мерж-коммитам: они всегда объясняют суть изменения и обозначают момент мержа целой ветки.
Изменения, которые уже попали в master , нельзя стирать из истории и не так просто отменить через git revert . Если все коммиты были объединены в один с помощью rebase , можно применить revert к этому единственному коммиту. Однако мы убеждены, что в объединении коммитов больше вреда, чем пользы. К счастью, git умеет отменять мерж-коммиты. Если вы передумали и хотите вернуть отменённый мерж-коммит, то применяйте revert к коммиту, созданному в результате первого revert . Git всё равно не позволит вам замержить один и тот же коммит дважды.
Чтобы это стало возможным, необходимо сначала создать этот мерж-коммит. Поэтому, если вы мержите вручную, добавляйте опцию —no-ff . Система управления репозиториями сделает это за вас в момент принятия мерж-реквеста.
Не меняйте порядок коммитов с помощью rebase

Git позволяет вам сделать ребейз feature-ветки на master , в результате чего коммиты этой ветки оказываются в истории после коммитов в master . Это позволяет сделать мерж без мерж-коммита и в результате у вас получается простая линейная история. Но здесь действует то же правило, что и с объединением коммитов: не трогайте то, что уже попало в удалённый репозиторий. Мы рекомендуем не ребейзить даже промежуточные результаты вашей работы, отданные на ревью через мерж-реквест.
Использование rebase вынуждает вас многократно разрешать одни и те же конфликты. В некоторых случах это можно сделать командой git rerere (reuse recorded resolutions). Но ещё проще — вовсе не ребейзить и разрешать конфликты всего один раз, при мерже. Чем с меньшим количеством мерж-конфликтов вы сталкиваетесь — тем лучше.
Чтобы избежать лишних конфликтов, нужно не слишком часто мержить master в feature-ветки. Давайте разберём три возможных причины мержа master куда-либо ещё: «подтягивание кода» (leveraging code), мерж-конфликты и долгоживущие ветки.
Если вам нужно «подтянуть» изменения из master в feature-ветку — обычно можно обойтись вытаскиванием (cherry-pick) одного нужного коммита.
Конфликт при мерже feature-ветки обычно разрешается с помощью создания мерж-коммита. Если строки вашего файла могут находиться в произвольном порядке, то можно избежать некоторых конфликтов с помощью настройки gitattributes. Например, в файле .gitattributes репозитория GitLab есть строка CHANGELOG merge=union , и это позволяет мержить список изменений автоматически.
Последняя ситуация, когда необходимо мержить master куда-то ещё — это использование долгоживущих веток, которые периодически нужно обновлять до актуального состояния. Мартин Фаулер в своей статье о feature-ветках рассуждает о практике непрерывной интеграции (continuous integration, CI). Мы в GitLab немного путаем CI с тестированием веток.
Цитируя Фаулера: «Я знаю людей, которые утверждают, что практикуют CI, потому что выполняют сборку каждой ветки и каждого коммита, и даже могут при этом использовать CI-сервер. То, что они делают, называется непрерывной сборкой (continuous building). Это тоже благородное дело, но интеграции-то нет, а значит, нет и «непрерывной интеграции».»
Решение заключается в том, что feature-ветки должны существовать недолго и быстро мержиться. Можно ориентироваться на срок в один рабочий день. Если разработчик держит ветку для реализации задачи более одного дня, подумайте о том, чтобы раздробить задачу на более мелкие части. В качестве альтернативы можно использовать «переключатели фич» (feature toggles).
Для работы с долгоживущими ветками есть две стратегии:
- Стратегия непрерывной интеграции предполагает, что вы мержите master в долгоживущую ветку в начале каждого дня,
чтобы предотвратить более сложные мержи в будущем. - Стратегия «точки синхронизации» (synchronization point strategy) разрешает мержить только строго определённые коммиты,
например отмеченые тегом релизы. Линус Торвальдс рекомендует именно такой способ, потому что код релизных версий лучше изучен.
GitLab EE предлагает возможность делать rebase непосредственно перед принятием мерж-реквеста. Вы можете включить эту возможность в настройках проекта, выбрав Merge Requests Rebase .

Перед принятием мерж-реквеста выберите опцию rebase before merge .

GitLab попытается сделать rebase перед мержем. Если rebase без конфликтов невозможен, будет выполнен обычный мерж.
В заключение хотелось бы сказать следующее: старайтесь делать меньше мерж-коммитов, но не исключайте их вовсе. Ваш код должен быть чистым, но его история должна быть достоверной. Разработка ПО происходит небольшими и не всегда красивыми шагами. То, что они сохранятся в истории кода — нормально. А ребейз делает историю недостоверной, после чего никакие инструменты не покажут вам действительную историю, потому что они не могут узнать идентификаторы коммитов, которые были до ребейза.
Используйте эмодзи в задачах и мерж-реквестах

Общепринятая практика — выражать одобрение или неодобрение с помощью кнопок +1 и -1.
В GitLab вы можете использовать эмодзи, чтобы, например, «дать пять» автору хорошей задачи или мерж-реквеста.
Пуш и удаление веток

Мы рекомендуем регулярно пушить локальные ветки в удалённый репозиторий, даже если код ещё не готов к ревью. Таким образом вы страхуетесь от ситуации, в которой кто-то другой начал работу над той же задачей. Разумеется, более правильный способ — назначить этой задаче исполнителя с помощью трекера задач. Но иногда этот способ даёт сбой, просто потому что никто об этом не вспомнил.
Когда ветка замержена в master , её можно удалить из репозитория. В GitLab и подобных ему системах это можно сделать непосредственно во время мержа. Это гарантирует, что при обзоре веток в системе управления репозиториями, вы увидите только те, над которыми действительно идёт работа. А ещё это освобождает имя и позволяет назвать им новую ветку. Это необходимо, если вы переоткрыли задачу и вам нужна новая ветка и новый мерж-реквест.
Делайте коммиты часто и пишите к ним корректные сообщения

Мы рекомендуем начать коммитить код как можно раньше и делать это регулярно. Каждый раз, когда у вас есть работающий набор из кода и тестов к нему, можно сделать коммит. Преимущество этого способа в том, что если следующий этап работы зайдёт в тупик, вы всегда сможете вернуться к рабочей версии кода. Это кардинально отличается от работы с SVN, где код можно коммитить только тогда, когда он полностью готов. Когда ваша работа завершена, используйте мерж/пулл-реквест, чтобы поделиться ей.
Сообщение коммита должно описывать ваши намерения, а не пересказывать содержимое кода — его и так несложно посмотреть. Важно то, зачем вы сделали этот коммит.
Пример хорошего сообщения: «Скобминировать шаблоны, чтобы разгрузить интерфейс пользователя».
Некоторые слова портят сообщение, потому что ничего конкретного не значат: «поменять», «улучшить», «отрефакторить» и т.п. Слова «чинит», «исправляет» тоже лучше не использовать, только если вы не пишете «fix» (только на английском) в конце сообщения и вместе с номером задачи. Если вы хотите больше подробностей, рекомендуем прочитать отличную статью из блога Tim Pope.
Тестирование перед мержем

В старых моделях рабочего процесса сервер непрерывной интеграции (CI server), как правило, запускал тесты только на ветке master . Поэтому разработчикам приходилось нести ответственность за то, чтобы не сломать master . В GitLab flow разработчики создают свои ветки от master , поэтому её всегда нужно поддерживать «зелёной». Поэтому каждый мерж-реквест нужно тестировать, прежде чем мержить. Инструменты CI, такие как GitLab CI или Travis, умеют показывать результаты сборки (build) непосредственно в мерж-реквесте.
Слабое место этого метода в том, что тестируется ветка, а не результат её мержа. Ошибки могут возникнуть в процессе мержа, поэтому более надёжно тестировать результат. Сложность этого подхода в том, что этот результат меняется каждый раз, когда в master попадают новые коммиты. Повторение тестов каждый раз, когда меняется master , потребует больших вычислительных ресурсов, так что вы гораздо чаще будете ждать, пока пройдут тесты.
Если ветки мержатся быстро и конфликтов при мерже нет, то обычно можно рискнуть и замержить, не тестируя результат. Если конфликты всё-таки есть, то можно замержить master в feature-ветку (т.е. наоборот), после чего ваш сервер CI запустит тесты на полученном коммите. Если feature-ветки живут дольше, чем несколько дней, стоит подумать об уменьшении масштаба ваших фич.
Мерж чужого кода в ваш код

Когда начинаете работу над задачей, всегда создавайте feature-ветку от последнего коммита в master . Только если ваша работа требует изменений из определённой ветки, начните с этой ветки. Если впоследствии вам понадобилось замержить другую ветку, обязательно объясните необходимость этого в сообщении мерж-коммита. Пока вы не запушили вашу ветку в общий репозиторий, можно ребейзить её на master или другую ветку. Не нужно мержить стабильные ветки в свои feature-ветки, если в этом нет строгой необходимости. Линус Торвальдс вообще запрещает мержить стабильные ветки в feature-ветки, за исключением крупных релизов.
Ссылки
- Git Flow, автор Vincent Driessen
- Эта статья в блоге GitLab
Gitflow workflow
Gitflow is a legacy Git workflow that was originally a disruptive and novel strategy for managing Git branches. Gitflow has fallen in popularity in favor of trunk-based workflows, which are now considered best practices for modern continuous software development and DevOps practices. Gitflow also can be challenging to use with CI/CD. This post details Gitflow for historical purposes.
What is Gitflow?
Gitflow is an alternative Git branching model that involves the use of feature branches and multiple primary branches. It was first published and made popular by Vincent Driessen at nvie. Compared to trunk-based development, Gitflow has numerous, longer-lived branches and larger commits. Under this model, developers create a feature branch and delay merging it to the main trunk branch until the feature is complete. These long-lived feature branches require more collaboration to merge and have a higher risk of deviating from the trunk branch. They can also introduce conflicting updates.
Gitflow can be used for projects that have a scheduled release cycle and for the DevOps best practice of continuous delivery. This workflow doesn’t add any new concepts or commands beyond what’s required for the Feature Branch Workflow. Instead, it assigns very specific roles to different branches and defines how and when they should interact. In addition to feature branches, it uses individual branches for preparing, maintaining, and recording releases. Of course, you also get to leverage all the benefits of the Feature Branch Workflow: pull requests, isolated experiments, and more efficient collaboration.

related material
Advanced Git log
SEE SOLUTION
Learn Git with Bitbucket Cloud
How it works
Develop and main branches
Instead of a single main branch, this workflow uses two branches to record the history of the project. The main branch stores the official release history, and the develop branch serves as an integration branch for features. It’s also convenient to tag all commits in the main branch with a version number.
The first step is to complement the default main with a develop branch. A simple way to do this is for one developer to create an empty develop branch locally and push it to the server:
git branch develop
git push -u origin develop
This branch will contain the complete history of the project, whereas main will contain an abridged version. Other developers should now clone the central repository and create a tracking branch for develop.
When using the git-flow extension library, executing git flow init on an existing repo will create the develop branch:
$ git flow init
Initialized empty Git repository in ~/project/.git/
No branches exist yet. Base branches must be created now.
Branch name for production releases: [main]
Branch name for "next release" development: [develop]
How to name your supporting branch prefixes?
Feature branches? [feature/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []
$ git branch
* develop
main
Feature branches
Step 1. Create the repository
Each new feature should reside in its own branch, which can be pushed to the central repository for backup/collaboration. But, instead of branching off of main , feature branches use develop as their parent branch. When a feature is complete, it gets merged back into develop. Features should never interact directly with main .
Note that feature branches combined with the develop branch is, for all intents and purposes, the Feature Branch Workflow. But, the Gitflow workflow doesn’t stop there.
Feature branches are generally created off to the latest develop branch.
Creating a feature branch
Without the git-flow extensions:
git checkout develop
git checkout -b feature_branch
When using the git-flow extension:
git flow feature start feature_branch
Continue your work and use Git like you normally would.
Finishing a feature branch
When you’re done with the development work on the feature, the next step is to merge the feature_branch into develop .
Without the git-flow extensions:
git checkout develop
git merge feature_branch
Using the git-flow extensions:
git flow feature finish feature_branch
Release branches
Once develop has acquired enough features for a release (or a predetermined release date is approaching), you fork a release branch off of develop . Creating this branch starts the next release cycle, so no new features can be added after this point—only bug fixes, documentation generation, and other release-oriented tasks should go in this branch. Once it’s ready to ship, the release branch gets merged into main and tagged with a version number. In addition, it should be merged back into develop , which may have progressed since the release was initiated.
Using a dedicated branch to prepare releases makes it possible for one team to polish the current release while another team continues working on features for the next release. It also creates well-defined phases of development (e.g., it’s easy to say, “This week we’re preparing for version 4.0,” and to actually see it in the structure of the repository).
Making release branches is another straightforward branching operation. Like feature branches, release branches are based on the develop branch. A new release branch can be created using the following methods.
Without the git-flow extensions:
git checkout develop
git checkout -b release/0.1.0
When using the git-flow extensions:
$ git flow release start 0.1.0
Switched to a new branch 'release/0.1.0'
Once the release is ready to ship, it will get merged it into main and develop , then the release branch will be deleted. It’s important to merge back into develop because critical updates may have been added to the release branch and they need to be accessible to new features. If your organization stresses code review, this would be an ideal place for a pull request.
To finish a release branch, use the following methods:
Without the git-flow extensions:
git checkout main
git merge release/0.1.0
Or with the git-flow extension:
git flow release finish '0.1.0'
Hotfix branches
Maintenance or “hotfix” branches are used to quickly patch production releases. Hotfix branches are a lot like release branches and feature branches except they’re based on main instead of develop . This is the only branch that should fork directly off of main . As soon as the fix is complete, it should be merged into both main and develop (or the current release branch), and main should be tagged with an updated version number.
Having a dedicated line of development for bug fixes lets your team address issues without interrupting the rest of the workflow or waiting for the next release cycle. You can think of maintenance branches as ad hoc release branches that work directly with main . A hotfix branch can be created using the following methods:
Without the git-flow extensions:
git checkout main
git checkout -b hotfix_branch
When using the git-flow extensions:
$ git flow hotfix start hotfix_branch
Similar to finishing a release branch, a hotfix branch gets merged into both main and develop.
git checkout main
git merge hotfix_branch
git checkout develop
git merge hotfix_branch
git branch -D hotfix_branch
$ git flow hotfix finish hotfix_branch
Example
A complete example demonstrating a Feature Branch Flow is as follows. Assuming we have a repo setup with a main branch.
git checkout main
git checkout -b develop
git checkout -b feature_branch
# work happens on feature branch
git checkout develop
git merge feature_branch
git checkout main
git merge develop
git branch -d feature_branch
In addition to the feature and release flow, a hotfix example is as follows:
git checkout main
git checkout -b hotfix_branch
# work is done commits are added to the hotfix_branch
git checkout develop
git merge hotfix_branch
git checkout main
git merge hotfix_branch
Summary
Here we discussed the Gitflow Workflow. Gitflow is one of many styles of Git workflows you and your team can utilize.
Some key takeaways to know about Gitflow are:
- The workflow is great for a release-based software workflow.
- Gitflow offers a dedicated channel for hotfixes to production.
The overall flow of Gitflow is:
1. A develop branch is created from main
2. A release branch is created from develop
3. Feature branches are created from develop
4. When a feature is complete it is merged into the develop branch
5. When the release branch is done it is merged into develop and main
6. If an issue in main is detected a hotfix branch is created from main
7. Once the hotfix is complete it is merged to both develop and main