- добавлены каноны и VitePress-сайт стратегии обновления шаблонов - подключена карточка документации на главной странице - добавлены сборочные скрипты, Caddy-маршрут и Docker-сборка - добавлена git-иконка для карточки и сгенерированы публичные артефакты
1010 lines
35 KiB
Plaintext
1010 lines
35 KiB
Plaintext
---
|
||
url: /template-sync-strategy/overview.md
|
||
description: >-
|
||
Управляемое обновление проектов от шаблона через чистую ветку template,
|
||
временные sync-ветки и PR/MR.
|
||
---
|
||
|
||
# Template Sync Strategy
|
||
|
||
Template Sync Strategy описывает процесс, при котором приложение создаётся от шаблона и дальше регулярно получает обновления шаблона без ручного копирования файлов.
|
||
|
||
Основной маршрут:
|
||
|
||
```text
|
||
templates/master -> template -> sync/* -> master
|
||
```
|
||
|
||
Где:
|
||
|
||
* `templates/master` — основная ветка внешнего репозитория шаблона.
|
||
* `template` — чистый слепок шаблона внутри репозитория приложения.
|
||
* `sync/*` — временная ветка, где шаблон накладывается на приложение.
|
||
* `master` — основная ветка приложения.
|
||
|
||
## Задача
|
||
|
||
Шаблон хорошо решает старт проекта: приносит CI/CD, Dockerfile, зависимости, линтер, сборку, структуру и базовую документацию. Но после старта приложения расходятся: где-то обновили CI, где-то забыли, где-то сделали локальную кастомизацию.
|
||
|
||
Стратегия нужна, чтобы шаблон оставался общей технической базой не только в первый день проекта, но и на всём жизненном цикле приложения.
|
||
|
||
## Главный принцип
|
||
|
||
Ветка `template` должна оставаться чистым слепком оригинального шаблона.
|
||
|
||
В неё нельзя коммитить изменения приложения и нельзя решать конфликты. Все конфликтные решения выполняются только во временных ветках `sync/*`.
|
||
|
||
## Состав документации
|
||
|
||
* [Зачем это нужно](./concepts/why.md) — какие проблемы появляются без update-flow.
|
||
* [Модель веток](./concepts/model.md) — роли `templates/master`, `template`, `sync/*` и `master`.
|
||
* [Правила процесса](./concepts/rules.md) — ограничения, которые удерживают схему чистой.
|
||
* [Новый проект от шаблона](./setup/clean-repository.md) — старт приложения с правильной историей.
|
||
* [Миграция существующего master](./setup/existing-master-migration.md) — одноразовое связывание несвязанных историй.
|
||
* [Обычное обновление шаблона](./workflows/update-template.md) — регулярный рабочий процесс.
|
||
* [Решение конфликтов](./workflows/resolve-conflicts.md) — где и как совместить шаблон с приложением.
|
||
* [Review и merge](./workflows/review-and-merge.md) — как доставлять sync-ветку в `master`.
|
||
* [Памятка](./reference/cheatsheet.md) — короткий набор команд.
|
||
* [Troubleshooting](./reference/troubleshooting.md) — типовые ошибки и диагностика.
|
||
* [Глоссарий](./reference/glossary.md) — основные термины.
|
||
|
||
---
|
||
|
||
---
|
||
url: /template-sync-strategy/concepts/why.md
|
||
description: >-
|
||
Почему шаблону нужен процесс обновления, а не только быстрый старт нового
|
||
проекта.
|
||
---
|
||
|
||
# Зачем это нужно
|
||
|
||
Шаблон закрывает повторяющуюся техническую базу проекта: CI/CD, Dockerfile, зависимости, lint, build, структуру каталогов и базовую документацию.
|
||
|
||
Это снимает рутину на старте. Команде не нужно каждый раз заново собирать одинаковый технический каркас.
|
||
|
||
## Проблема после старта
|
||
|
||
Создать проект легко. Поддерживать 10-20 проектов сложнее.
|
||
|
||
Сначала проекты похожи. Потом они начинают расходиться:
|
||
|
||
* В одном проекте обновили CI, в другом забыли.
|
||
* В одном проекте Dockerfile остался из шаблона, в другом его локально поправили.
|
||
* В одном проекте зависимости уже свежие, в другом остались старые версии.
|
||
* В одном проекте изменения шаблона перенесли руками, в другом потеряли.
|
||
|
||
Без процесса обновления шаблон перестаёт быть общей основой. Он остаётся только способом быстро создать первый коммит.
|
||
|
||
## Что ломается без стратегии
|
||
|
||
Когда шаблон нельзя нормально обновлять:
|
||
|
||
* проекты начинают жить своей жизнью;
|
||
* граница между шаблоном и приложением теряется;
|
||
* обновления превращаются в ручное копирование;
|
||
* конфликты решаются прямо в рабочих ветках;
|
||
* становится непонятно, какой проект на какой версии шаблона;
|
||
* Git-история перестаёт быть источником правды.
|
||
|
||
Это особенно больно, когда приложений много. Для одного проекта ручной перенос ещё можно пережить. Для набора проектов нужен единый маршрут обновления.
|
||
|
||
## Цель стратегии
|
||
|
||
Стратегия не пытается убрать конфликты полностью. Она делает так, чтобы конфликты возникали в предсказуемом месте, проходили review и не ломали чистую ветку шаблона.
|
||
|
||
Главная формулировка:
|
||
|
||
> Шаблон должен обновляться так же контролируемо, как обычная фича: через ветку, проверку и PR/MR.
|
||
|
||
---
|
||
|
||
---
|
||
url: /template-sync-strategy/concepts/model.md
|
||
description: Роли веток и remote в стратегии обновления проекта от шаблона.
|
||
---
|
||
|
||
# Модель веток
|
||
|
||
Целевая схема:
|
||
|
||
```text
|
||
templates/master -> template -> sync/* -> master
|
||
```
|
||
|
||
Это логическая модель ответственности. Она не требует физически разделять файлы шаблона и приложения по папкам.
|
||
|
||
## templates/master
|
||
|
||
`templates/master` — это `master` из репозитория шаблона.
|
||
|
||
В репозитории приложения он доступен через remote `templates`:
|
||
|
||
```bash
|
||
git remote add templates <template-repo-url>
|
||
git fetch templates
|
||
```
|
||
|
||
Этот remote считается источником обновлений шаблона.
|
||
|
||
## template
|
||
|
||
`template` — чистый слепок шаблона внутри репозитория приложения.
|
||
|
||
Его задача — показать, какая версия шаблонной базы сейчас доступна приложению.
|
||
|
||
В `template` нельзя коммитить руками изменения приложения. Эта ветка обновляется только из `templates/master`.
|
||
|
||
## master
|
||
|
||
`master` — основная ветка приложения.
|
||
|
||
Она содержит:
|
||
|
||
* базу шаблона;
|
||
* продуктовый код;
|
||
* локальные настройки приложения;
|
||
* историю применения обновлений шаблона.
|
||
|
||
`master` не используется как место ручного решения конфликтов при обновлении шаблона.
|
||
|
||
## sync/\*
|
||
|
||
`sync/*` — временная ветка для обновления приложения от шаблона.
|
||
|
||
Она создаётся от актуального `origin/master`, после чего в неё вливается `origin/template`.
|
||
|
||
Пример:
|
||
|
||
```bash
|
||
git fetch origin
|
||
git switch -c sync/update-template-v2 origin/master
|
||
git merge origin/template
|
||
```
|
||
|
||
Если появляются конфликты, они решаются именно в этой ветке.
|
||
|
||
## Почему нужен отдельный sync-слой
|
||
|
||
Нельзя безопасно использовать `template` как source branch для прямого PR/MR в `master`: если возникнет конфликт, решение может попасть в `template`.
|
||
|
||
После этого `template` перестанет быть чистым слепком шаблона. Git начнёт видеть в ней не только шаблон, но и локальные решения конкретного приложения.
|
||
|
||
`sync/*` можно пачкать conflict resolve-коммитами, проверками и правками совместимости. Эта ветка временная и удаляется после merge.
|
||
|
||
---
|
||
|
||
---
|
||
url: /template-sync-strategy/concepts/rules.md
|
||
description: >-
|
||
Набор правил, который удерживает template чистой, а обновления шаблона
|
||
контролируемыми.
|
||
---
|
||
|
||
# Правила процесса
|
||
|
||
Небольшой набор правил удерживает схему чистой.
|
||
|
||
## Делаем
|
||
|
||
* `template` обновляем только из `templates/master`.
|
||
* `sync/*` создаём от `origin/master`.
|
||
* `origin/template` вливаем в `sync/*`, а не напрямую в `master`.
|
||
* Конфликты решаем только в `sync/*`.
|
||
* `sync/* -> master` вливаем через PR/MR.
|
||
* Для sync-PR/MR отключаем squash.
|
||
|
||
## Не делаем
|
||
|
||
* Не правим `template` руками.
|
||
* Не коммитим изменения приложения в `template`.
|
||
* Не мержим `template -> master` напрямую.
|
||
* Не решаем конфликты в `master`.
|
||
* Не включаем squash для `sync/* -> master`.
|
||
|
||
## Почему squash нельзя
|
||
|
||
Squash может уничтожить нормальную связь истории `master` с историей `template`.
|
||
|
||
Git использует историю, чтобы понимать, какие изменения шаблона уже были доставлены в приложение. Если результат обновления шаблона превратить в один squash-коммит, связь с исходными коммитами шаблона станет хуже или исчезнет.
|
||
|
||
Для sync-PR/MR допустимы:
|
||
|
||
```text
|
||
fast-forward merge = хорошо
|
||
merge commit = допустимо
|
||
squash merge = нельзя
|
||
```
|
||
|
||
## Почему template нельзя пачкать
|
||
|
||
`template` — эталонный слепок оригинального шаблона.
|
||
|
||
Если в неё попадает локальное решение конфликта или изменение приложения, она перестаёт отвечать на вопрос: “какая версия шаблона сейчас подключена к приложению?”.
|
||
|
||
После этого ломается главная граница ответственности: шаблон отдельно, приложение отдельно, конфликтная зона отдельно.
|
||
|
||
---
|
||
|
||
---
|
||
url: /template-sync-strategy/setup/clean-repository.md
|
||
description: Старт нового приложения от шаблонного репозитория с правильной историей веток.
|
||
---
|
||
|
||
# Новый проект от шаблона
|
||
|
||
Этот сценарий подходит, когда репозиторий приложения ещё пустой или его можно безопасно пересоздать от шаблона.
|
||
|
||
Целевая модель:
|
||
|
||
```text
|
||
templates/master -> template -> sync/* -> master
|
||
```
|
||
|
||
## Условия
|
||
|
||
Есть два репозитория:
|
||
|
||
```text
|
||
template repo = репозиторий шаблона
|
||
app repo = репозиторий приложения
|
||
```
|
||
|
||
В обоих репозиториях основная ветка называется `master`.
|
||
|
||
## Подготовить шаблон
|
||
|
||
В репозитории шаблона:
|
||
|
||
```bash
|
||
cd /path/to/template-repo
|
||
git switch master
|
||
```
|
||
|
||
Если это пустой репозиторий, добавьте первый файл и запушьте `master`:
|
||
|
||
```bash
|
||
printf "# Template Repository\n\nBase template version: v1\n" > README.md
|
||
git add README.md
|
||
git commit -m "docs: добавить базовый шаблон"
|
||
git push -u origin master
|
||
```
|
||
|
||
## Подключить шаблон в приложении
|
||
|
||
В репозитории приложения:
|
||
|
||
```bash
|
||
cd /path/to/app-repo
|
||
git remote add templates <template-repo-url>
|
||
git fetch templates
|
||
```
|
||
|
||
Создайте ветку `template` от шаблона:
|
||
|
||
```bash
|
||
git switch -c template templates/master
|
||
git push -u origin template
|
||
```
|
||
|
||
Создайте ветку приложения `master` от `template`:
|
||
|
||
```bash
|
||
git switch -c master template
|
||
```
|
||
|
||
Добавьте слой приложения:
|
||
|
||
```bash
|
||
mkdir -p app
|
||
printf "Application code v1\n" > app/app.txt
|
||
git add app/app.txt
|
||
git commit -m "feat: добавить слой приложения"
|
||
git push -u origin master
|
||
```
|
||
|
||
После этого история выглядит так:
|
||
|
||
```text
|
||
template: T1
|
||
master: T1---A1
|
||
```
|
||
|
||
Где `T1` — коммит шаблона, а `A1` — коммит приложения.
|
||
|
||
## Настроить pull и push для template
|
||
|
||
Можно сделать так, чтобы на ветке `template`:
|
||
|
||
```text
|
||
git pull тянул из templates/master
|
||
git push пушил в origin/template
|
||
```
|
||
|
||
Команды:
|
||
|
||
```bash
|
||
git config branch.template.remote templates
|
||
git config branch.template.merge refs/heads/master
|
||
git config branch.template.pushRemote origin
|
||
```
|
||
|
||
Дополнительно можно запретить случайный push в репозиторий шаблона:
|
||
|
||
```bash
|
||
git remote set-url --push templates DISABLED
|
||
```
|
||
|
||
## Дальше
|
||
|
||
После первичной настройки постоянные ветки такие:
|
||
|
||
```text
|
||
template = чистый шаблон
|
||
master = приложение
|
||
```
|
||
|
||
Обновления шаблона выполняются через временные ветки `sync/*` по инструкции [Обычное обновление шаблона](../workflows/update-template.md).
|
||
|
||
---
|
||
|
||
---
|
||
url: /template-sync-strategy/setup/existing-master-migration.md
|
||
description: >-
|
||
Как одноразово связать master приложения с историей шаблона, если проект был
|
||
создан отдельно.
|
||
---
|
||
|
||
# Миграция существующего master
|
||
|
||
Этот сценарий нужен, если в репозитории приложения уже есть `master`, но он был создан не от шаблона.
|
||
|
||
## Проблема
|
||
|
||
Если `master` приложения и `template` имеют разные корневые коммиты, Git видит две несвязанные истории.
|
||
|
||
Плохое состояние:
|
||
|
||
```text
|
||
template: T1---T2---T3
|
||
|
||
master: A1---A2
|
||
```
|
||
|
||
При попытке выполнить обычный merge Git может ответить:
|
||
|
||
```text
|
||
fatal: отказ слияния несвязанных историй изменений
|
||
```
|
||
|
||
Это означает, что у веток нет общего предка.
|
||
|
||
## Цель миграции
|
||
|
||
Нужно один раз связать истории, чтобы дальше обновления шаблона шли обычным merge-процессом.
|
||
|
||
После миграции история будет выглядеть примерно так:
|
||
|
||
```text
|
||
template: T1---T2---T3
|
||
\
|
||
master: A1---A2-----M
|
||
```
|
||
|
||
Где `M` — одноразовый merge-коммит, который связал историю приложения с историей шаблона.
|
||
|
||
## Подключить репозиторий шаблона
|
||
|
||
В репозитории приложения:
|
||
|
||
```bash
|
||
cd /path/to/app-repo
|
||
git remote add templates <template-repo-url>
|
||
git fetch templates
|
||
git fetch origin
|
||
```
|
||
|
||
Если remote `templates` уже существует:
|
||
|
||
```bash
|
||
git fetch templates
|
||
git fetch origin
|
||
```
|
||
|
||
## Создать или обновить template
|
||
|
||
Если ветки `template` ещё нет:
|
||
|
||
```bash
|
||
git switch -c template templates/master
|
||
git push -u origin template
|
||
```
|
||
|
||
Если ветка `template` уже есть:
|
||
|
||
```bash
|
||
git switch template
|
||
git merge --ff-only templates/master
|
||
git push origin template
|
||
```
|
||
|
||
Опционально настройте удобное поведение `pull` и `push`:
|
||
|
||
```bash
|
||
git config branch.template.remote templates
|
||
git config branch.template.merge refs/heads/master
|
||
git config branch.template.pushRemote origin
|
||
git remote set-url --push templates DISABLED
|
||
```
|
||
|
||
## Связать master с template
|
||
|
||
Создайте временную ветку от текущего приложения:
|
||
|
||
```bash
|
||
git fetch origin
|
||
git switch -c sync/bootstrap-template origin/master
|
||
```
|
||
|
||
Слейте шаблон с разрешением несвязанных историй:
|
||
|
||
```bash
|
||
git merge --allow-unrelated-histories origin/template
|
||
```
|
||
|
||
Если есть конфликты, решите их в ветке `sync/bootstrap-template`:
|
||
|
||
```bash
|
||
git add .
|
||
git commit
|
||
```
|
||
|
||
Если конфликтов не было, Git сам создаст merge-коммит.
|
||
|
||
Запушьте ветку:
|
||
|
||
```bash
|
||
git push -u origin sync/bootstrap-template
|
||
```
|
||
|
||
Дальше через UI или локально смержите:
|
||
|
||
```text
|
||
sync/bootstrap-template -> master
|
||
```
|
||
|
||
## Что проверить перед merge
|
||
|
||
Посмотрите граф истории:
|
||
|
||
```bash
|
||
git --no-pager log --oneline --graph --decorate --all --max-count=50
|
||
```
|
||
|
||
Убедитесь, что `sync/bootstrap-template` содержит и историю приложения, и историю шаблона.
|
||
|
||
Посмотрите итоговый diff:
|
||
|
||
```bash
|
||
git --no-pager diff origin/master...sync/bootstrap-template
|
||
```
|
||
|
||
## Когда миграцию делать не стоит
|
||
|
||
Не стоит связывать истории, если приложение только что создано и его можно безопасно пересоздать от шаблона.
|
||
|
||
Для нового проекта лучше сделать чистый старт по инструкции [Новый проект от шаблона](./clean-repository.md).
|
||
|
||
---
|
||
|
||
---
|
||
url: /template-sync-strategy/workflows/update-template.md
|
||
description: >-
|
||
Повторяемый процесс доставки изменений шаблона в приложение после первичной
|
||
настройки.
|
||
---
|
||
|
||
# Обычное обновление шаблона
|
||
|
||
Эта инструкция подходит после любого стартового сценария:
|
||
|
||
* [Новый проект от шаблона](../setup/clean-repository.md).
|
||
* [Миграция существующего master](../setup/existing-master-migration.md).
|
||
|
||
Целевой маршрут:
|
||
|
||
```text
|
||
templates/master -> template -> sync/* -> master
|
||
```
|
||
|
||
## 1. Обновить слепок шаблона
|
||
|
||
В репозитории приложения:
|
||
|
||
```bash
|
||
cd /path/to/app-repo
|
||
git switch template
|
||
git pull --ff-only
|
||
git push
|
||
```
|
||
|
||
Этот вариант работает, если для ветки `template` настроено:
|
||
|
||
```text
|
||
pull из templates/master
|
||
push в origin/template
|
||
```
|
||
|
||
Явная форма без зависимости от tracking-настроек:
|
||
|
||
```bash
|
||
git fetch templates
|
||
git switch template
|
||
git merge --ff-only templates/master
|
||
git push origin template
|
||
```
|
||
|
||
Если `--ff-only` падает, значит `template` перестал быть чистым слепком шаблона. Остановитесь и разберите причину до продолжения.
|
||
|
||
Проверьте, что `origin/template` обновился до шаблона:
|
||
|
||
```bash
|
||
git fetch origin
|
||
git fetch templates
|
||
git --no-pager log --oneline -1 origin/template
|
||
git --no-pager log --oneline -1 templates/master
|
||
```
|
||
|
||
Оба коммита должны совпадать.
|
||
|
||
## 2. Создать ветку обновления приложения
|
||
|
||
После обновления `template` создайте временную ветку от текущего приложения:
|
||
|
||
```bash
|
||
git fetch origin
|
||
git switch -c sync/update-template-v2 origin/master
|
||
git merge origin/template
|
||
```
|
||
|
||
Имя ветки можно менять под версию или дату:
|
||
|
||
```text
|
||
sync/update-template-v2
|
||
sync/update-template-2026-05-09
|
||
sync/update-template-1.8.0
|
||
```
|
||
|
||
Проверьте, что временная ветка реально отличается от `origin/master` изменениями шаблона:
|
||
|
||
```bash
|
||
git --no-pager diff --stat origin/master...HEAD
|
||
```
|
||
|
||
Если diff пустой, значит обновлённый `origin/template` не был влит в `sync/*` ветку или в шаблоне нет новых изменений.
|
||
|
||
## 3. Решить конфликты
|
||
|
||
Если есть конфликты, решайте их именно в `sync/*`.
|
||
|
||
После решения конфликтов:
|
||
|
||
```bash
|
||
git add .
|
||
git commit
|
||
```
|
||
|
||
Если конфликтов не было, Git сам создаст merge-коммит или выполнит fast-forward, в зависимости от истории.
|
||
|
||
## 4. Запушить sync-ветку
|
||
|
||
```bash
|
||
git push -u origin sync/update-template-v2
|
||
```
|
||
|
||
Дальше откройте PR/MR:
|
||
|
||
```text
|
||
source: sync/update-template-v2
|
||
target: master
|
||
```
|
||
|
||
Правила merge описаны в [Review и merge](./review-and-merge.md).
|
||
|
||
---
|
||
|
||
---
|
||
url: /template-sync-strategy/workflows/resolve-conflicts.md
|
||
description: Почему конфликты при обновлении шаблона должны решаться только в sync-ветках.
|
||
---
|
||
|
||
# Решение конфликтов
|
||
|
||
Конфликт при обновлении шаблона — нормальная ситуация. Важно не то, что конфликт возник, а где он возник.
|
||
|
||
Правильное место для конфликтов — временная ветка `sync/*`.
|
||
|
||
## Пример
|
||
|
||
Шаблон поменял строку в `README.md`:
|
||
|
||
```text
|
||
Base template version: template-conflict-v10
|
||
```
|
||
|
||
Приложение поменяло ту же строку иначе:
|
||
|
||
```text
|
||
Base template version: application-conflict-v10
|
||
```
|
||
|
||
При merge `origin/template` в `sync/update-template-v10` появится конфликт:
|
||
|
||
```text
|
||
<<<<<<< HEAD
|
||
Base template version: application-conflict-v10
|
||
=======
|
||
Base template version: template-conflict-v10
|
||
>>>>>>> origin/template
|
||
```
|
||
|
||
Это правильное место конфликта: `master` ещё не изменён, `template` остаётся чистой, а итоговое решение можно проверить в PR/MR.
|
||
|
||
## Как решать
|
||
|
||
1. Оставайтесь в ветке `sync/*`.
|
||
2. Разберите конфликт по смыслу: что должно остаться в приложении после обновления шаблона.
|
||
3. Удалите conflict markers.
|
||
4. Проверьте проект локально.
|
||
5. Закоммитьте результат.
|
||
|
||
```bash
|
||
git status
|
||
git add .
|
||
git commit
|
||
```
|
||
|
||
## Что нельзя делать
|
||
|
||
Нельзя переносить conflict resolve в `template`.
|
||
|
||
`template` должна совпадать с шаблоном. Если решение конфликта попадёт туда, она перестанет быть эталоном и дальнейшие обновления станут менее предсказуемыми.
|
||
|
||
Нельзя решать конфликт прямо в `master`, потому что основная ветка приложения должна получать только проверенный результат через PR/MR.
|
||
|
||
## Что проверить после resolve
|
||
|
||
Посмотрите статус:
|
||
|
||
```bash
|
||
git status
|
||
```
|
||
|
||
Посмотрите diff относительно текущего приложения:
|
||
|
||
```bash
|
||
git --no-pager diff origin/master...HEAD
|
||
```
|
||
|
||
Посмотрите граф:
|
||
|
||
```bash
|
||
git --no-pager log --oneline --graph --decorate --all --max-count=50
|
||
```
|
||
|
||
---
|
||
|
||
---
|
||
url: /template-sync-strategy/workflows/review-and-merge.md
|
||
description: Как проверять и вливать sync-ветку с обновлением шаблона в master приложения.
|
||
---
|
||
|
||
# Review и merge
|
||
|
||
После подготовки `sync/*` ветки обновление шаблона должно попасть в `master` через PR/MR.
|
||
|
||
## Создать PR/MR
|
||
|
||
Параметры:
|
||
|
||
```text
|
||
source: sync/update-template-vX
|
||
target: master
|
||
```
|
||
|
||
Цель review — увидеть:
|
||
|
||
* какие изменения пришли из шаблона;
|
||
* какие конфликтные решения были сделаны в `sync/*`;
|
||
* не попали ли в обновление лишние изменения приложения;
|
||
* проходят ли проверки проекта.
|
||
|
||
## Настройки merge
|
||
|
||
Для sync-PR/MR важно:
|
||
|
||
```text
|
||
squash = off
|
||
fast-forward merge = хорошо
|
||
merge commit = допустимо
|
||
squash merge = нельзя
|
||
```
|
||
|
||
Squash нельзя использовать, потому что он может уничтожить связь истории `master` с историей `template`. Особенно это критично после миграционного `sync/bootstrap-template`.
|
||
|
||
## Проверки перед merge
|
||
|
||
Проверьте граф истории:
|
||
|
||
```bash
|
||
git --no-pager log --oneline --graph --decorate --all --max-count=50
|
||
```
|
||
|
||
Проверьте итоговый diff:
|
||
|
||
```bash
|
||
git --no-pager diff origin/master...sync/update-template-vX
|
||
```
|
||
|
||
Проверьте проект обычными командами конкретного приложения, например:
|
||
|
||
```bash
|
||
npm run lint
|
||
npm run build
|
||
```
|
||
|
||
## После merge
|
||
|
||
После успешного merge в `master` можно удалить временную ветку:
|
||
|
||
```bash
|
||
git branch -d sync/update-template-vX
|
||
git push origin --delete sync/update-template-vX
|
||
```
|
||
|
||
Проверьте, что `master` теперь содержит обновление шаблона:
|
||
|
||
```bash
|
||
git fetch origin
|
||
git --no-pager log origin/template..origin/master --oneline
|
||
git --no-pager diff origin/template...origin/master
|
||
```
|
||
|
||
---
|
||
|
||
---
|
||
url: /template-sync-strategy/reference/cheatsheet.md
|
||
description: Короткий набор команд для регулярного обновления приложения от шаблона.
|
||
---
|
||
|
||
# Памятка
|
||
|
||
Рабочая схема:
|
||
|
||
```text
|
||
templates/master -> template -> sync/* -> master
|
||
```
|
||
|
||
## Обновить template
|
||
|
||
В репозитории приложения:
|
||
|
||
```bash
|
||
git switch template
|
||
git pull --ff-only
|
||
git push
|
||
```
|
||
|
||
Это подтягивает свежий шаблон из `templates/master` и пушит его в `origin/template`.
|
||
|
||
## Создать ветку обновления
|
||
|
||
```bash
|
||
git fetch origin
|
||
git switch -c sync/update-template-vX origin/master
|
||
git merge origin/template
|
||
```
|
||
|
||
Если есть конфликты, решить их в этой же ветке:
|
||
|
||
```bash
|
||
git add .
|
||
git commit
|
||
```
|
||
|
||
## Запушить sync-ветку
|
||
|
||
```bash
|
||
git push -u origin sync/update-template-vX
|
||
```
|
||
|
||
## Влить через UI
|
||
|
||
Создать PR/MR:
|
||
|
||
```text
|
||
source: sync/update-template-vX
|
||
target: master
|
||
```
|
||
|
||
Важно:
|
||
|
||
```text
|
||
squash = off
|
||
```
|
||
|
||
## Проверка
|
||
|
||
```bash
|
||
git --no-pager log --oneline --graph --decorate --all --max-count=30
|
||
```
|
||
|
||
## Суть процесса
|
||
|
||
1. Обновить `template` из `templates/master`.
|
||
2. Создать `sync/*` от `origin/master`.
|
||
3. Влить `origin/template` в `sync/*`.
|
||
4. Решить конфликты, если есть.
|
||
5. Запушить `sync/*`.
|
||
6. Через UI влить `sync/* -> master`.
|
||
|
||
---
|
||
|
||
---
|
||
url: /template-sync-strategy/reference/troubleshooting.md
|
||
description: Типовые ошибки при обновлении проекта от шаблона и способы диагностики.
|
||
---
|
||
|
||
# Troubleshooting
|
||
|
||
## fatal: отказ слияния несвязанных историй изменений
|
||
|
||
Ошибка:
|
||
|
||
```text
|
||
fatal: отказ слияния несвязанных историй изменений
|
||
```
|
||
|
||
Причина: `master` приложения не был создан от `template`, поэтому у веток нет общего предка.
|
||
|
||
Решение: выполнить одноразовую миграцию через `sync/bootstrap-template` по инструкции [Миграция существующего master](../setup/existing-master-migration.md).
|
||
|
||
Коротко:
|
||
|
||
```bash
|
||
git switch -c sync/bootstrap-template origin/master
|
||
git merge --allow-unrelated-histories origin/template
|
||
git push -u origin sync/bootstrap-template
|
||
```
|
||
|
||
## --ff-only падает на template
|
||
|
||
Ошибка возникает при команде:
|
||
|
||
```bash
|
||
git merge --ff-only templates/master
|
||
```
|
||
|
||
Причина: в `template` появились коммиты, которых нет в шаблоне. Значит ветка перестала быть чистым слепком.
|
||
|
||
Что проверить:
|
||
|
||
```bash
|
||
git fetch templates
|
||
git --no-pager log --oneline --graph --decorate templates/master..template
|
||
```
|
||
|
||
Решение зависит от причины. Не продолжайте обновление, пока не станет понятно, какие локальные коммиты попали в `template`.
|
||
|
||
## Пустой diff в sync-ветке
|
||
|
||
Симптом:
|
||
|
||
```bash
|
||
git --no-pager diff --stat origin/master...HEAD
|
||
```
|
||
|
||
не показывает изменений.
|
||
|
||
Возможные причины:
|
||
|
||
* в шаблоне нет новых изменений;
|
||
* `origin/template` не был обновлён;
|
||
* `origin/template` не был влит в `sync/*`;
|
||
* sync-ветка создана не от актуального `origin/master`.
|
||
|
||
Что проверить:
|
||
|
||
```bash
|
||
git fetch origin
|
||
git fetch templates
|
||
git --no-pager log --oneline -1 origin/template
|
||
git --no-pager log --oneline -1 templates/master
|
||
git --no-pager log --oneline --graph --decorate --all --max-count=50
|
||
```
|
||
|
||
## Случайно включили squash
|
||
|
||
Если sync-PR/MR уже влит squash-merge, история шаблона могла не сохраниться как нормальная merge-связь.
|
||
|
||
Что сделать:
|
||
|
||
* зафиксировать факт в описании проекта;
|
||
* проверить, видит ли Git последующие обновления шаблона без повторного применения старых изменений;
|
||
* при следующем обновлении внимательно смотреть diff и конфликты;
|
||
* для будущих sync-PR/MR отключить squash.
|
||
|
||
Если ситуация стала неуправляемой, может потребоваться отдельная техническая миграция истории.
|
||
|
||
## cannot run less
|
||
|
||
Ошибка:
|
||
|
||
```text
|
||
cannot run less
|
||
```
|
||
|
||
Причина: Git пытается открыть pager `less`, которого нет в системе.
|
||
|
||
Решение: использовать `git --no-pager`:
|
||
|
||
```bash
|
||
git --no-pager log --oneline --graph --decorate --all --max-count=50
|
||
git --no-pager diff template...master
|
||
```
|
||
|
||
---
|
||
|
||
---
|
||
url: /template-sync-strategy/reference/glossary.md
|
||
description: 'Термины, которые используются в Template Sync Strategy.'
|
||
---
|
||
|
||
# Глоссарий
|
||
|
||
## Template repo
|
||
|
||
Репозиторий шаблона. В нём живёт общая техническая база: CI/CD, Dockerfile, зависимости, линтер, сборка, структура и документация.
|
||
|
||
## App repo
|
||
|
||
Репозиторий приложения. В нём живёт продуктовый код и локальные настройки конкретного приложения.
|
||
|
||
## templates
|
||
|
||
Git remote внутри репозитория приложения, который указывает на репозиторий шаблона.
|
||
|
||
Пример:
|
||
|
||
```bash
|
||
git remote add templates <template-repo-url>
|
||
```
|
||
|
||
## templates/master
|
||
|
||
Ветка `master` из репозитория шаблона, доступная в приложении через remote `templates`.
|
||
|
||
## template
|
||
|
||
Ветка внутри репозитория приложения, которая должна быть чистым слепком `templates/master`.
|
||
|
||
## master
|
||
|
||
Основная ветка приложения. Содержит шаблонную базу плюс продуктовый слой.
|
||
|
||
## sync/\*
|
||
|
||
Временные ветки для обновления приложения от шаблона. Создаются от `origin/master`, получают merge из `origin/template`, проходят review и затем вливаются в `master`.
|
||
|
||
## Fast-forward
|
||
|
||
Обновление ветки без merge-коммита, когда текущая ветка может быть просто передвинута вперёд по истории.
|
||
|
||
## Merge commit
|
||
|
||
Коммит слияния, который сохраняет связь двух историй. Допустим для `sync/* -> master`.
|
||
|
||
## Squash
|
||
|
||
Способ merge, при котором все изменения source branch превращаются в один новый коммит. Для sync-PR/MR запрещён, потому что может разрушить полезную связь истории `master` с историей `template`.
|