# Git flow: гілки develop, release і hotfix

> Модель гілок, зорієнтована на релізи: довгоживучі main і develop, гілки feature, release-гілка для кожної версії, гілки hotfix і теги на main. Коли вона доречна (релізи через магазини застосунків, кілька підтримуваних версій), чому багато вебкоманд перейшли на GitHub flow чи trunk-based development і як упізнати модель за списком гілок.

- Курс: [Git і GitHub для продактів](https://productovi.com/uk/courses/git-for-product.md)
- Модуль: Командні воркфлоу
- Урок 11/15, ~39 хв
- Джерело: https://productovi.com/uk/courses/git-for-product/git-flow

## «Нормальні релізи»

**Alex Tutor:** Новий тиждень у продуктовій команді Котокорму, і банер осіннього розпродажу вже на сайті.

**Sofia:** Банер розпродажу з'явився в понеділок о 8:00, хвилина в хвилину. А за обідом CEO спитав, чому в нас немає «нормальних релізів, як у всіх серйозних компаній».

**Alex Tutor:** Деякі серйозні компанії справді так працюють. Daniel, ти ж працював так до Котокорму?

**Daniel:** Три роки на фітнес-застосунку для телефонів. Нова версія кожні два тижні, і кожну перевіряли Apple і Google, перш ніж користувачі могли її завантажити. Ми працювали за **git flow**.

**Alex Tutor:** Git flow це модель гілок, яку вперше описали в популярній статті 2010 року. Її головна ідея: дві гілки, що живуть завжди, `main` і `develop`, плюс три види тимчасових.

```text
Граф комітів, від найстарішого: Git flow у команді мобільного застосунку
1. коміт 2c71a0e у main "Version 2.7.0", тег v2.7.0
2. гілка develop починається від коміту 2c71a0e
3. коміт 4d8e2b1 у develop "Update translations"
4. гілка feature/workout-reminders починається від коміту 4d8e2b1
5. коміт 7a3f9c2 у feature/workout-reminders "Add reminder settings"
6. гілка hotfix/2.7.1 починається від коміту 2c71a0e
7. коміт c5e0d38 у hotfix/2.7.1 "Fix crash on login" (виділено)
8. мердж-коміт e8b2f14: hotfix/2.7.1 змерджено в main "Merge hotfix/2.7.1", тег v2.7.1
9. мердж-коміт 0f6c3a9: hotfix/2.7.1 змерджено в develop "Merge hotfix/2.7.1 into develop"
10. коміт 91be4d7 у feature/workout-reminders "Send reminder notifications"
11. мердж-коміт 5b9d7e2: feature/workout-reminders змерджено в develop "Merge feature/workout-reminders"
12. гілка release/2.8.0 починається від коміту 5b9d7e2
13. коміт a4c1e86 у release/2.8.0 "Bump version to 2.8.0"
14. коміт 3e7f0b5 у release/2.8.0 "Fix reminder text on small screens"
15. мердж-коміт 6d2a9f3: release/2.8.0 змерджено в main "Merge release/2.8.0", тег v2.8.0
16. мердж-коміт b8e4c71: release/2.8.0 змерджено в develop "Merge release/2.8.0 into develop"
```

*У main лише випущені версії, кожна з тегом. develop збирає наступний реліз. Фічі відгалужуються від develop і повертаються в неї; релізну гілку відрізають від develop і мерджать у main та назад у develop; хотфікс починається від main і потрапляє в обидві.*

**Sofia:** П'ять доріжок замість нашої однієї з короткими гілками. І мерджі в обидва боки.

**Alex Tutor:** Читай доріжку за доріжкою. У `main` лише випущені версії, і кожен коміт у ній отримує тег: `v2.7.0`, `v2.7.1`, `v2.8.0`. У `develop` збирають наступну версію. В оригінальній статті першу гілку називали `master`.

**Daniel:** Далі тимчасові. `feature/*` для кожної фічі, `release/*` для підготовки однієї версії, `hotfix/*` для термінового виправлення того, що вже є в користувачів.

**Daniel:** І ми завжди мерджили через мердж-коміт, ніколи через squash, тож кожна фіча лишалася помітною в `develop` окремою петлею. Саме так радить оригінальна модель.

> **Вправа:** Зістав кожну гілку git flow з її роботою.

## Змерджено ще не означає випущено

**Sofia:** Тобто фічу мерджать у `develop`, а не в `main`. Користувачі її тоді отримують?

**Daniel:** Ні. Змерджено в `develop` означає «буде в наступній версії». Нагадування про тренування змерджили посеред спринту, а на телефони людей вони потрапили майже через два тижні.

**Alex Tutor:** Для продакта це найбільша різниця. У нашому GitHub flow змерджено означає «на сайті за кілька хвилин». У git flow змерджено означає «у потязі», а потяг вирушає за розкладом.

![Готова посилка разом з іншими чекає на складі наступної вантажівки, а в іншому кінці міста покупці чекають біля дверей.](https://productovi.com/courses/git-for-product/inline/git-flow-illustration-2.webp)

**Sofia:** Тобто в тій команді корисне питання «в якому це релізі?», а не «чи це змерджено?»

**Daniel:** Саме це питання навчився ставити наш маркетинг. Через «змерджено» вони анонсували речі, яких користувачі ще не бачили.

**Alex Tutor:** GitHub показує цю різницю, якщо читати уважно. У шапці pull request написано, що його змерджено «into develop» (у develop), а найновіший тег досі стара версія.

> **Вправа:** У git flow, щойно `feature/workout-reminders` змерджено в `develop`, користувачі, які оновлять застосунок, отримають нагадування про тренування.

**Alex Tutor:** Спробуй це як рядок статусу, який маркетинг справді читає.

> **Вправа:** У колишній команді Daniel (git flow) нагадування змерджили в `develop` у вівторок. Наступну релізну гілку відгалузять у понеділок. Який статус ти опублікуєш для маркетингу?

## Відрізаємо release-гілку

**Alex Tutor:** **Release-гілка** (релізна гілка) це місце, де одна версія готується до випуску. Коли в `develop` набирається достатньо для наступної версії, її відрізають від `develop`: `release/2.8.0`. З цієї миті це окрема доріжка.

**Daniel:** У релізній гілці ми лише виправляли баги, міняли номер версії й писали нотатки до релізу. Жодних нових фіч. Тестувальники тиждень ганяли її вздовж і впоперек.

**Alex Tutor:** Тим часом `develop` лишається відкритою, тож нові фічі для 2.9.0 далі надходять. Коли реліз готовий, його мерджать у `main`, ставлять тег `v2.8.0` і мерджать назад у `develop`, щоб його виправлення не загубилися.

**Sofia:** А фіча, яку змерджили в `develop` через день після того, як відрізали реліз?

**Daniel:** Запізнилася на потяг. Чекає на 2.9.0. Тому дата відрізання була найважливішою датою в нашому календарі, і продакти щоспринту за неї боролися.

![У git flow фіча, змерджена в develop, чекає на відрізання релізу, тиждень тестування й перевірку в магазині; користувачі бачать її лише після оновлення, майже через два тижні.](https://productovi.com/courses/git-for-product/diagrams/m4-l2-release-train-uk.png)

![Потяг рушає зі станції, а людина з посилкою вибігає на перон надто пізно; наступний потяг видно далеко на колії.](https://productovi.com/courses/git-for-product/inline/git-flow-illustration-3.webp)

*Не встигли до дати відгалуження — фіча поїде наступним релізом.*

**Alex Tutor:** Для планування git flow дає календар: дата відрізання, тиждень стабілізації, дата релізу. Роадмапи в таких командах часто виглядають як «2.8.0: нагадування, 2.9.0: цілі за кроками».

**Sofia:** Звучить доволі передбачувано.

**Daniel:** Для календаря так. Ціна це очікування: навіть однорядкове виправлення в `develop` їде наступним потягом, якщо воно не настільки термінове, щоб робити хотфікс.

> **Вправа:** Які фічі отримають користувачі у версії 2.8.0?

**Alex Tutor:** Саме за дату відгалуження PM сперечалися кожного спринту. Правда чи ні?

> **Вправа:** У git flow `release/2.8.0` відгалузили від `develop` у понеділок. Фіча, змерджена в `develop` у вівторок, усе одно вийде в 2.8.0, якщо її змерджать до тегу `v2.8.0`.

## Hotfix-гілки

**Sofia:** А якщо щось ламається в користувачів між релізами? Чекати два тижні?

**Daniel:** Не у випадку краху. Версія 2.7.0 падала під час входу в декого з користувачів. Ми відгалузили `hotfix/2.7.1` прямо від `main`, від тегу `v2.7.0`, виправили лише це і випустили за два дні.

**Alex Tutor:** **Хотфікс** починається від того, що є в користувачів, а не від `develop`, де повно невипущеної роботи. Його мерджать у `main` з новим тегом `v2.7.1` і в `develop`, щоб наступний реліз не повернув краш.

![Механік латає колесо авто, що вже їде дорогою з водієм, а позаду в гаражі на підйомниках стоять недороблені нові машини.](https://productovi.com/courses/git-for-product/inline/git-flow-illustration-4.webp)

*Хотфікс починають від того, що вже мають користувачі, а потім повертають у поточну роботу.*

**Daniel:** Один нюанс: якщо в цей момент відкрита релізна гілка, виправлення йде в неї замість `develop`. У `develop` воно потрапить, коли реліз змерджать назад.

**Sofia:** А чому важливо, щоб воно поверталося? Користувачі ж уже отримали виправлення.

**Daniel:** Бо 2.8.0 збирають із `develop`. Забудеш змерджити назад, і версія 2.8.0 знову падатиме під час входу. Я бачив таке один раз. Одного разу вистачило.

> **Вправа:** У git flow версія 2.7.0 застосунку в частини користувачів падає під час входу. Розстав кроки хотфіксу по порядку.

**Alex Tutor:** Тепер нюанс від Daniel: а якщо в цей момент відкрита релізна гілка?

> **Вправа:** У git flow `hotfix/2.7.1` виправляє краш під час входу. У цей момент `release/2.8.0` уже відкрита для тестування. Куди, крім `main`, треба злити хотфікс?

## Коли git flow доречний

**Alex Tutor:** Git flow доречний, коли реліз це подія: мобільний застосунок, що проходить перевірку в магазині, програма, яку клієнти встановлюють і оновлюють коли заманеться, або кілька версій, які підтримують одночасно.

**Sofia:** А для сайту, як у нас, де завжди працює лише одна версія?

**Alex Tutor:** Тоді `develop` здебільшого додає очікування й подвійні мерджі. Багато вебкоманд перейшли на GitHub flow або на **trunk-based development** (розробку в основній гілці): усі мерджать малі зміни в `main` щонайменше щодня, а флаги ховають те, що ще не готове.

**Alex Tutor:** З цим погодився навіть автор моделі. У 2020 році до оригінальної статті додали примітку: для вебзастосунків, які викладають безперервно, краще пасує простіший воркфлоу на кшталт GitHub flow, а git flow лишається для програм із явними версіями. Порівняння поруч: [git flow чи GitHub flow](/uk/blog/github-flow-vs-git-flow).

**Daniel:** Це збігається з моїм досвідом. Для застосунку він був саме те. Тут він би нас лише гальмував.

**Sofia:** А як trunk-based виглядає в щоденній роботі?

**Daniel:** Гілки живуть години, а не дні. Половину фічі мерджиш у вівторок, вимкненою, а другу половину в середу. Для цього потрібні дуже добрі автотести й чимало дисципліни.

> **Вправа:** Якій команді git flow пасує найприродніше?

## Упізнай модель за списком гілок

**Alex Tutor:** Ти зустрінеш усі три в інших репозиторіях: у застосунку партнера, в агенції, на наступній роботі. Сторінка гілок видає модель за лічені секунди.

```text
Гілки репозиторію фітнес-застосунку
- [Branch] develop: Default (основна) · оновлено сьогодні
- [Branch] main: Оновлено 9 днів тому · тег v2.8.0
- [Branch] release/2.9.0: Оновлено вчора · на 3 коміти попереду develop
- [Branch] feature/step-goals: Оновлено 2 години тому · pull request у develop
- [Branch] hotfix/2.8.1: Оновлено годину тому · pull request у main
```

**Alex Tutor:** `develop` поруч із `main`, плюс назви `release/…` і `hotfix/…`: це git flow. Часто `develop` навіть основна гілка репозиторію, тож нові pull requests за замовчуванням ідуть у неї.

**Daniel:** Лише `main` і кілька свіжих гілок `fix/…` чи `feature/…` з pull requests: це GitHub flow, як у нас. Майже нічого, крім `main`, гілки живуть години, багато флагів: trunk-based.

**Sofia:** Тоді старий репозиторій Daniel це хрестоматійний приклад: `develop` як основна, релізна гілка й хотфікс одночасно.

**Sofia:** А сторінка тегів покаже, чи вони взагалі нумерують версії.

> **Вправа:** Зістав список гілок кожного репозиторію з моделлю, яку там найімовірніше використовують.

## Анонси, коли релізи ходять потягом

**Alex Tutor:** Тепер на хвилину уяви себе в старій команді Daniel, того тижня, коли змерджили нагадування. Маркетинг бачить у командному чаті «нагадування змерджено» і хоче анонсувати їх у п'ятницю.

**Daniel:** Релізну гілку відрізають наступного понеділка, потім тиждень тестування, потім перевірка в магазині, зазвичай день-два.

**Sofia:** І навіть тоді користувачі мають оновити застосунок, щоб щось побачити.

**Alex Tutor:** Напиши відповідь для маркетингу. Два-три речення.

> **Вправа:** Ти продакт у старій команді Daniel, що робить застосунок. `feature/workout-reminders` змерджили в `develop` у вівторок. `release/2.8.0` відрізають наступного понеділка, тиждень тестують, потім надсилають у магазини (перевірка зазвичай триває день-два). Маркетинг питає: «Нагадування змерджено, можна анонсувати в цю п'ятницю?» Дай відповідь у 2–3 реченнях.

## Чи варто Котокорму перейти?

**Sofia:** Повернімося до CEO. Він хоче відповідь, а не лекцію про доріжки.

**Alex Tutor:** Тоді з'ясуй, що його насправді турбує. «Нормальні релізи» зазвичай означає «хочу знати, що змінилося, і бути певним, що нічого не зламається».

**Daniel:** І те, і інше ми можемо мати без `develop`. Частина «що змінилося» буде на наступному уроці: теги й нотатки до релізів.

**Alex Tutor:** Напиши йому коротку рекомендацію. Спершу відповідь, потім аргументи.

> **Вправа:** Напиши CEO коротку рекомендацію: чи варто Котокорму переходити на git flow?

**Sofia:** Отже, моя відповідь на «нормальні релізи»: так номерам версій і нотаткам до релізів, ні гілці `develop`.

**Daniel:** Цього тижня я поставлю наш перший тег. Бери каву й питання про те, що означає `v1.4.0`.

- Попередній урок: [GitHub flow: малі гілки, швидкі мерджі](https://productovi.com/uk/courses/git-for-product/github-flow.md)
- Наступний урок: [Релізи на GitHub і версії: теги, SemVer, changelog](https://productovi.com/uk/courses/git-for-product/releases-and-versions.md)

---
Productovi Learning. Безкоштовно, читати можна без реєстрації.
