diff --git a/GIT_BRANCH_DEPENDENCIES.ru.md b/tutorials/git/GIT_BRANCH_DEPENDENCIES.ru.md similarity index 100% rename from GIT_BRANCH_DEPENDENCIES.ru.md rename to tutorials/git/GIT_BRANCH_DEPENDENCIES.ru.md diff --git a/GIT_CONFIG.ru.md b/tutorials/git/GIT_CONFIG.ru.md similarity index 100% rename from GIT_CONFIG.ru.md rename to tutorials/git/GIT_CONFIG.ru.md diff --git a/tutorials/git/GIT_FLOW.ru.md b/tutorials/git/GIT_FLOW.ru.md new file mode 100644 index 0000000..02f6063 --- /dev/null +++ b/tutorials/git/GIT_FLOW.ru.md @@ -0,0 +1,1201 @@ +# Git Flow: правила разработки в команде + +## Назначение + +Этот документ описывает принятый в команде порядок работы с Git Flow: + +- какие ветки используются; +- от каких веток создавать новые; +- куда вливать изменения; +- как работать с `feature`, `release`, `hotfix`; +- как работать с зависимыми feature; +- как синхронизировать локальные ветки; +- как безопасно публиковать изменения; +- что делать через Pull Request. + +Цель — сделать историю изменений предсказуемой и избежать ситуаций, когда изменения случайно попадают не в ту ветку. + +--- + +## 1. Основная модель веток + +В классическом Git Flow используются две основные долгоживущие ветки: + +- `main` — код, находящийся в production; +- `develop` — основная ветка текущей разработки. + +Временные ветки: + +- `feature/*` — разработка новой функциональности; +- `release/*` — подготовка релиза; +- `hotfix/*` — срочное исправление production; +- `bugfix/*` — исправление ошибок в процессе разработки; +- `support/*` — поддержка старых версий, если это необходимо проекту. + +Базовая схема: + +```text + feature/* + / \ + / \ + / \ +main ─────────────────●──────────────●───────────── + ↑ ↑ + │ │ + release hotfix + │ │ + └──────┐ ┌─────┘ + ↓ ↓ +develop ────────────────●────●─●────────────────── + ↑ + │ + feature +``` + +Главное правило: + +```text +feature/* → develop +release/* → main +release/* → develop +hotfix/* → main +hotfix/* → develop +``` + +--- + +# 2. Что является источником для каждой ветки + +## Feature + +Feature создаётся от: + +```text +develop → feature/* +``` + +Пример: + +```bash +git flow feature start user-profile +``` + +Получается: + +```text +develop + \ + feature/user-profile +``` + +Новые feature по умолчанию **не создаются от `main`**. + +--- + +## Release + +Release создаётся от: + +```text +develop → release/* +``` + +Пример: + +```bash +git flow release start 2.4.0 +``` + +Получается: + +```text +develop + \ + release/2.4.0 +``` + +Release используется для подготовки уже готового набора изменений к production. + +В release обычно не добавляют новые большие функциональные возможности. + +--- + +## Hotfix + +Hotfix создаётся от: + +```text +main → hotfix/* +``` + +Пример: + +```bash +git flow hotfix start 2.4.1 +``` + +Используйте `hotfix`, когда проблема уже находится в production и исправление нельзя ждать до следующего обычного релиза. + +--- + +## Bugfix + +`bugfix` используется для исправления ошибок в процессе разработки. + +В зависимости от конфигурации `git-flow` такая ветка обычно является веткой разработки и должна в конечном итоге попасть в `develop`. + +Пример: + +```bash +git flow bugfix start fix-registration +``` + +--- + +# 3. Основной рабочий цикл Feature + +Обычная разработка выглядит так: + +```text +develop + │ + ├── feature/login + │ + ├── feature/payment + │ + └── feature/profile + │ + └────────→ develop +``` + +## Шаг 1. Обновить develop + +Перед началом работы необходимо синхронизировать локальный `develop`: + +```bash +git checkout develop +git pull origin develop +``` + +## Шаг 2. Создать feature + +```bash +git flow feature start user-profile +``` + +## Шаг 3. Работать и делать коммиты + +```bash +git add . +git commit -m "feat: add user profile" +``` + +Коммиты должны быть небольшими и логически связанными. + +## Шаг 4. Опубликовать feature + +Если работа ведётся через remote: + +```bash +git flow feature publish user-profile +``` + +или: + +```bash +git push -u origin feature/user-profile +``` + +## Шаг 5. Создать Pull Request + +Из: + +```text +feature/user-profile +``` + +в: + +```text +develop +``` + +После ревью и успешного прохождения CI изменения можно вливать в `develop`. + +--- + +# 4. Как вливать Feature в develop + +Есть два допустимых варианта. + +## Вариант A — через Pull Request + +Для командной разработки это предпочтительный способ: + +```text +feature/user-profile + │ + │ Pull Request + ↓ + develop +``` + +Плюсы: + +- code review; +- автоматические проверки; +- прозрачная история; +- возможность обсуждать изменения до merge. + +--- + +## Вариант B — через git-flow локально + +Можно использовать: + +```bash +git flow feature finish user-profile +``` + +Эта команда завершает feature и вливает её в `develop`. + +После этого изменения нужно отправить в remote: + +```bash +git push origin develop +``` + +Если проект использует обязательный Pull Request, локальный `feature finish` обычно не используется для финального merge. + +--- + +# 5. Важно: не все Feature должны зависеть друг от друга + +Предпочтительная структура: + +```text +develop + ├── feature/A + ├── feature/B + └── feature/C +``` + +Нежелательная структура: + +```text +develop + └── feature/A + └── feature/B + └── feature/C +``` + +Каждая feature по возможности должна начинаться от `develop`. + +--- + +# 6. Что делать, если Feature зависит от другой Feature + +Иногда `feature/B` действительно требует незавершённых изменений из `feature/A`. + +Например: + +```text +develop + \ + feature/A + \ + feature/B +``` + +В этом случае временно допустимо создать `feature/B` от `feature/A`. + +Пример: + +```bash +git checkout feature/A +git checkout -b feature/B +``` + +Но нужно понимать, что теперь B зависит от A. + +После завершения A желательно вернуть B на обычную базу: + +```text +develop + ├── feature/A + └── feature/B +``` + +Например, после merge A в `develop`: + +```bash +git checkout feature/B +git rebase develop +``` + +или выполнить merge: + +```bash +git checkout feature/B +git merge develop +``` + +Выбор между `rebase` и `merge` зависит от правил проекта. + +Главное правило: + +> Зависимая feature — временное исключение, а не стандартная структура проекта. + +Подробнее о зависимостях см. `GIT_BRANCH_DEPENDENCIES.ru.md`. + +--- + +# 7. Как обновлять Feature от develop + +Пока feature разрабатывается, в `develop` могут появляться новые изменения. + +Периодически feature необходимо синхронизировать. + +### Вариант с rebase + +```bash +git checkout feature/user-profile +git fetch origin +git rebase origin/develop +``` + +### Вариант с merge + +```bash +git checkout feature/user-profile +git fetch origin +git merge origin/develop +``` + +Необходимо использовать тот вариант, который принят в правилах конкретного репозитория. + +Если используется `rebase` для уже опубликованной ветки, после него может понадобиться: + +```bash +git push --force-with-lease +``` + +Использовать: + +```bash +git push --force +``` + +не рекомендуется. + +Подробнее о безопасном использовании `--force-with-lease` см. в: + +`GIT_FORCE_WITH_LEASE_RECOVERY.ru.md` + +--- + +# 8. Release Flow + +Когда набор изменений готов к релизу: + +```text +develop + │ + └──→ release/2.4.0 +``` + +Создание: + +```bash +git flow release start 2.4.0 +``` + +Далее выполняется: + +- финальное тестирование; +- исправление найденных ошибок; +- обновление версии; +- подготовка release notes; +- подготовка production-конфигурации. + +Когда release готов: + +```text +release/2.4.0 → main +release/2.4.0 → develop +``` + +То есть результат релиза должен оказаться одновременно: + +```text +main +``` + +и + +```text +develop +``` + +Пример: + +```bash +git flow release finish 2.4.0 +``` + +После чего изменения необходимо отправить в remote: + +```bash +git push origin main +git push origin develop +git push origin --tags +``` + +Конкретная последовательность зависит от используемого процесса CI/CD. + +--- + +# 9. Почему release вливается и в main, и в develop + +Предположим: + +```text +develop + \ + release/2.4.0 +``` + +Во время подготовки релиза нашли bug и исправили его в release. + +Если отправить изменения только в `main`: + +```text +release → main +``` + +то исправление может не попасть обратно в будущую разработку. + +Поэтому используется: + +```text +release → main +release → develop +``` + +Таким образом, `develop` не теряет исправления, сделанные во время подготовки релиза. + +--- + +# 10. Hotfix Flow + +Если production сломан и исправление требуется срочно: + +```text +main + \ + hotfix/2.4.1 +``` + +Создание: + +```bash +git flow hotfix start 2.4.1 +``` + +После исправления hotfix должен попасть: + +```text +hotfix/2.4.1 → main +hotfix/2.4.1 → develop +``` + +Пример: + +```bash +git flow hotfix finish 2.4.1 +``` + +После этого изменения публикуются: + +```bash +git push origin main +git push origin develop +git push origin --tags +``` + +--- + +# 11. Bugfix Flow + +Если ошибка обнаружена во время разработки и не требует отдельного production hotfix: + +```text +develop + \ + bugfix/registration +``` + +Создание: + +```bash +git flow bugfix start registration +``` + +После завершения: + +```text +bugfix/registration → develop +``` + +Использование `bugfix` или обычного `feature` для исправления ошибки определяется соглашениями проекта. + +Главное — не создавать production hotfix от `develop`. + +--- + +# 12. Support Flow + +`support/*` нужен только тогда, когда проект действительно поддерживает старые версии. + +Например: + +```text +main + ├── 3.0 + └── support/2.x +``` + +Такие ветки позволяют поддерживать старую версию отдельно от основной разработки. + +Использование `support/*` должно быть явно согласовано командой. + +Если проект не требует поддержки нескольких версий одновременно, `support` лучше не использовать без необходимости. + +--- + +# 13. Публикация веток + +Для feature: + +```bash +git flow feature publish +``` + +Для остальных типов веток используются соответствующие `publish`/`push` команды согласно конфигурации `git-flow`. + +Перед публикацией необходимо убедиться, что ветка имеет правильное имя и базовую ветку. + +Проверить ветки можно: + +```bash +git branch +git branch -r +``` + +Полезно также посмотреть историю: + +```bash +git log --all --graph --decorate --oneline +``` + +Это один из самых удобных способов визуально проверить, куда действительно идут изменения. + +--- + +# 14. От какого типа ветки что создаём + +| Ветка | Создаётся от | Основное назначение | Куда вливается | +|---|---|---|---| +| `feature/*` | `develop` | Новая функциональность | `develop` | +| `bugfix/*` | `develop` | Исправление ошибки в разработке | `develop` | +| `release/*` | `develop` | Подготовка релиза | `main` и `develop` | +| `hotfix/*` | `main` | Срочное production-исправление | `main` и `develop` | +| `support/*` | зависит от процесса | Поддержка старой версии | зависит от процесса | + +--- + +# 15. Что не следует делать + +## Не создавать Feature от main + +Плохо: + +```text +main + \ + feature/new-payment +``` + +Правильно: + +```text +develop + \ + feature/new-payment +``` + +--- + +## Не вливать Feature напрямую в main + +Обычно: + +```text +feature → develop → release → main +``` + +а не: + +```text +feature → main +``` + +--- + +## Не создавать Hotfix от develop + +Плохо: + +```text +develop → hotfix +``` + +Правильно: + +```text +main → hotfix +``` + +--- + +## Не держать Feature зависимой от другой Feature без необходимости + +Плохо: + +```text +feature/A + \ + feature/B + \ + feature/C +``` + +Лучше: + +```text +develop + ├── feature/A + ├── feature/B + └── feature/C +``` + +--- + +## Не выполнять force push без необходимости + +Опасно: + +```bash +git push --force +``` + +Предпочтительно: + +```bash +git push --force-with-lease +``` + +при условии, что force push разрешён правилами репозитория. + +--- + +# 16. Рекомендуемый командный процесс + +Для обычной задачи: + +```text +1. develop + ↓ +2. feature/* + ↓ +3. commits + ↓ +4. push + ↓ +5. Pull Request + ↓ +6. review + CI + ↓ +7. develop + ↓ +8. release/* + ↓ +9. main +``` + +В виде схемы: + +```text + Pull Request +feature/login ─────────────────────────→ develop + │ + │ release + ↓ + release/2.4.0 + │ + ┌──────────┴──────────┐ + ↓ ↓ + main develop +``` + +--- + +# 17. Правила Pull Request + +Для командной работы рекомендуется: + +1. Один PR — одна логическая задача. +2. Целевая ветка PR должна быть заранее определена. +3. PR должен проходить CI до merge. +4. Автор PR не должен самостоятельно обходить обязательные проверки. +5. Конфликты необходимо разрешать в своей рабочей ветке, а не в `develop`/`main`. +6. Не следует смешивать в одном PR feature, рефакторинг и несвязанные исправления. +7. После изменения истории feature-ветки необходимо убедиться, что PR всё ещё содержит только нужные изменения. + +Рекомендуемая схема: + +```text +feature/* → Pull Request → develop +release/* → Pull Request → main +hotfix/* → Pull Request → main +``` + +Если политика проекта допускает отдельный merge release/hotfix в `develop`, это также должно быть явно зафиксировано в правилах репозитория. + +--- + +# 18. Конвенция именования веток + +Название ветки должно быть коротким и отражать задачу. + +Примеры: + +```text +feature/user-profile +feature/payment-api +feature/checkout-flow + +bugfix/registration-error +bugfix/incorrect-total + +release/2.4.0 + +hotfix/2.4.1 + +support/2.x +``` + +Не рекомендуется: + +```text +feature/test +feature/new +feature/fix +feature/ivan +feature/123 +``` + +Если в проекте используется трекер задач, предпочтительно включать идентификатор задачи: + +```text +feature/PROJ-123-user-profile +bugfix/PROJ-456-invalid-total +``` + +Точная схема именования должна быть одинаковой для всей команды. + +--- + +# 19. Коммиты + +Коммиты должны быть: + +- небольшими; +- законченными; +- логически связанными; +- понятными без чтения всего diff. + +Плохо: + +```bash +git commit -m "fix" +git commit -m "changes" +git commit -m "test" +``` + +Лучше: + +```bash +git commit -m "feat: add user profile endpoint" +git commit -m "fix: validate empty email" +git commit -m "test: cover invalid payment status" +``` + +Если проект использует Conventional Commits, придерживаемся его правил: + +```text +feat: +fix: +refactor: +test: +docs: +chore: +build: +ci: +``` + +--- + +# 20. Синхронизация перед началом работы + +Перед созданием новой feature: + +```bash +git fetch origin +git checkout develop +git pull --ff-only origin develop +``` + +После этого: + +```bash +git flow feature start my-feature +``` + +Для `hotfix`: + +```bash +git fetch origin +git checkout main +git pull --ff-only origin main +git flow hotfix start 2.4.1 +``` + +Использование `--ff-only` помогает не создавать случайные локальные merge-коммиты во время обычного обновления базовой ветки. + +--- + +# 21. Что делать при конфликтах + +Если конфликт возник при `rebase`: + +```bash +git status +``` + +Исправить конфликтующие файлы, затем: + +```bash +git add +git rebase --continue +``` + +Чтобы полностью отменить rebase: + +```bash +git rebase --abort +``` + +Если конфликт возник при merge: + +```bash +git status +``` + +После исправления: + +```bash +git add +git commit +``` + +Если merge необходимо отменить: + +```bash +git merge --abort +``` + +Не следует разрешать конфликты вслепую. После разрешения обязательно проверить diff и тесты. + +--- + +# 22. Удаление завершённых веток + +После merge завершённая feature обычно больше не нужна. + +Локальную ветку можно удалить: + +```bash +git branch -d feature/my-feature +``` + +Удалённую ветку: + +```bash +git push origin --delete feature/my-feature +``` + +Если репозиторий автоматически удаляет ветку после merge, вручную удалять её не нужно. + +Не удаляйте ветку до тех пор, пока не убедились, что нужные изменения действительно попали в целевую ветку. + +--- + +# 23. Как проверить поток коммитов + +Для просмотра всех локальных и remote веток: + +```bash +git log --all --graph --decorate --oneline --date-order +``` + +Полезно также: + +```bash +git branch -a +``` + +и: + +```bash +git show-branch --all +``` + +Пример графа: + +```text +* abc1234 (main) Merge release/2.4.0 +|\ +| * def5678 (release/2.4.0) Prepare release 2.4.0 +| * 123abcd Fix release configuration +|/ +* 456efgh (develop) Merge feature/payment +|\ +| * 789ijkl (feature/payment) Add payment service +| * 012mnop Add payment validation +|/ +* 345qrst Previous release +``` + +Такой граф позволяет быстро проверить: + +- от какой ветки была создана ветка; +- какие изменения в неё попали; +- где находится merge; +- не ушла ли feature в неправильную ветку. + +--- + +# 24. Частые ошибки + +## Feature создана от старого develop + +Симптом: + +```text +feature + \ + старый develop +``` + +Решение — сначала синхронизировать feature с актуальным `develop`. + +--- + +## Feature случайно создана от main + +Не продолжайте разработку, не проверив ситуацию. + +Сначала нужно убедиться, какие изменения уже появились в feature, и только после этого выбрать способ переноса на актуальный `develop`. + +В зависимости от ситуации это может быть: + +```bash +git rebase develop +``` + +или пересоздание ветки от правильной базы. + +--- + +## В hotfix попали незавершённые изменения из develop + +Это обычно означает, что hotfix создавался не от актуального `main`. + +Hotfix должен базироваться на том состоянии, которое реально находится в production. + +--- + +## Исправление сделано только в release + +Если release содержит важный bugfix, он должен попасть и в `main`, и обратно в `develop`. + +Нельзя оставлять важные исправления только внутри временной release-ветки. + +--- + +## Два разработчика одновременно переписали историю одной feature + +Не следует выполнять `rebase`/force push общей ветки без согласования. + +Для опубликованных веток безопаснее: + +```bash +git push --force-with-lease +``` + +Но даже `--force-with-lease` не отменяет необходимость договориться с остальными участниками. + +Подробнее: `GIT_FORCE_WITH_LEASE_RECOVERY.ru.md`. + +--- + +# 25. Полная схема Git Flow + +```text + feature/A + / + / + ● + / + / +develop ────────────────●────────●───────────────●──────── + \ / + \ / + \ / + release/2.4.0 + │ + ┌────────┴────────┐ + ↓ ↓ + main develop + │ + │ + └── hotfix/2.4.1 + │ + ┌────────┴────────┐ + ↓ ↓ + main develop +``` + +Для обычной разработки поток выглядит так: + +```text +develop + │ + ├── feature/A ──────────────┐ + │ ↓ + ├── feature/B ─────────→ develop + │ + └── feature/C ──────────────┘ + │ + ↓ + release/2.4.0 + │ + ┌─────┴─────┐ + ↓ ↓ + main develop +``` + +--- + +# 26. Краткая памятка + +Запоминаем: + +```text +feature ← develop +feature → develop + +bugfix ← develop +bugfix → develop + +release ← develop +release → main +release → develop + +hotfix ← main +hotfix → main +hotfix → develop +``` + +Основные команды: + +```bash +# Feature +git flow feature start +git flow feature publish +git flow feature finish + +# Bugfix +git flow bugfix start +git flow bugfix finish + +# Release +git flow release start +git flow release finish + +# Hotfix +git flow hotfix start +git flow hotfix finish + +# Support +git flow support start +``` + +Для просмотра графа: + +```bash +git log --all --graph --decorate --oneline --date-order +``` + +--- + +# 27. Наше командное правило + +Перед каждой операцией с ветками нужно ответить на три вопроса: + +**1. От какой ветки я создаю текущую ветку?** + +**2. В какую ветку должны попасть мои изменения?** + +**3. Не содержит ли моя ветка изменений, которые не должны попасть в целевую ветку?** + +Если на эти три вопроса есть однозначный ответ, операция с Git почти всегда становится предсказуемой. + +--- + +# 28. Итог + +Нормальный Git Flow в команде выглядит так: + +```text + feature + ↗ +develop ───────────────●─────────────── + │ + │ release + ↓ + main + │ + │ hotfix + ↓ + develop +``` + +Ключевая идея проста: + +> `develop` — источник обычной разработки, `main` — источник production-правок. Feature идут в `develop`, release — в `main` и обратно в `develop`, hotfix — из `main` в `main` и обратно в `develop`. + +Git Flow — это не набор обязательных магических команд. Это договорённость команды о том, **где рождаются изменения, через какие этапы проходят и в какую ветку попадают**. + +Перед merge всегда проверяем целевую ветку, актуальность базы, CI и содержимое diff. diff --git a/GIT_FORCE_WITH_LEASE_RECOVERY.ru.md b/tutorials/git/GIT_FORCE_WITH_LEASE_RECOVERY.ru.md similarity index 100% rename from GIT_FORCE_WITH_LEASE_RECOVERY.ru.md rename to tutorials/git/GIT_FORCE_WITH_LEASE_RECOVERY.ru.md