refactor: перенести сборку в проекты
- перенесены каноны и VitePress-конфиги в projects/<slug> - добавлены корневой и проектные build.ts для сборки артефактов - добавлены shared-библиотеки сборки в projects/_shared/lib - обновлены CI, Dockerfile, package.json, gitignore и README - удалена сборка frontend-агента
This commit is contained in:
72
projects/template-sync-strategy/canons/concepts/model.md
Normal file
72
projects/template-sync-strategy/canons/concepts/model.md
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
title: Модель веток
|
||||
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.
|
||||
47
projects/template-sync-strategy/canons/concepts/rules.md
Normal file
47
projects/template-sync-strategy/canons/concepts/rules.md
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: Правила процесса
|
||||
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` — эталонный слепок оригинального шаблона.
|
||||
|
||||
Если в неё попадает локальное решение конфликта или изменение приложения, она перестаёт отвечать на вопрос: “какая версия шаблона сейчас подключена к приложению?”.
|
||||
|
||||
После этого ломается главная граница ответственности: шаблон отдельно, приложение отдельно, конфликтная зона отдельно.
|
||||
44
projects/template-sync-strategy/canons/concepts/why.md
Normal file
44
projects/template-sync-strategy/canons/concepts/why.md
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: Зачем это нужно
|
||||
description: Почему шаблону нужен процесс обновления, а не только быстрый старт нового проекта.
|
||||
---
|
||||
|
||||
# Зачем это нужно
|
||||
|
||||
Шаблон закрывает повторяющуюся техническую базу проекта: CI/CD, Dockerfile, зависимости, lint, build, структуру каталогов и базовую документацию.
|
||||
|
||||
Это снимает рутину на старте. Команде не нужно каждый раз заново собирать одинаковый технический каркас.
|
||||
|
||||
## Проблема после старта
|
||||
|
||||
Создать проект легко. Поддерживать 10-20 проектов сложнее.
|
||||
|
||||
Сначала проекты похожи. Потом они начинают расходиться:
|
||||
|
||||
- В одном проекте обновили CI, в другом забыли.
|
||||
- В одном проекте Dockerfile остался из шаблона, в другом его локально поправили.
|
||||
- В одном проекте зависимости уже свежие, в другом остались старые версии.
|
||||
- В одном проекте изменения шаблона перенесли руками, в другом потеряли.
|
||||
|
||||
Без процесса обновления шаблон перестаёт быть общей основой. Он остаётся только способом быстро создать первый коммит.
|
||||
|
||||
## Что ломается без стратегии
|
||||
|
||||
Когда шаблон нельзя нормально обновлять:
|
||||
|
||||
- проекты начинают жить своей жизнью;
|
||||
- граница между шаблоном и приложением теряется;
|
||||
- обновления превращаются в ручное копирование;
|
||||
- конфликты решаются прямо в рабочих ветках;
|
||||
- становится непонятно, какой проект на какой версии шаблона;
|
||||
- Git-история перестаёт быть источником правды.
|
||||
|
||||
Это особенно больно, когда приложений много. Для одного проекта ручной перенос ещё можно пережить. Для набора проектов нужен единый маршрут обновления.
|
||||
|
||||
## Цель стратегии
|
||||
|
||||
Стратегия не пытается убрать конфликты полностью. Она делает так, чтобы конфликты возникали в предсказуемом месте, проходили review и не ломали чистую ветку шаблона.
|
||||
|
||||
Главная формулировка:
|
||||
|
||||
> Шаблон должен обновляться так же контролируемо, как обычная фича: через ветку, проверку и PR/MR.
|
||||
48
projects/template-sync-strategy/canons/index.md
Normal file
48
projects/template-sync-strategy/canons/index.md
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: Template Sync Strategy
|
||||
description: Управляемое обновление проектов от шаблона через чистую ветку template, временные sync-ветки и PR/MR.
|
||||
keywords: [template sync, шаблон проекта, обновление шаблона, git template, sync branch, template branch]
|
||||
---
|
||||
|
||||
# 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) — основные термины.
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
title: Памятка
|
||||
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`.
|
||||
52
projects/template-sync-strategy/canons/reference/glossary.md
Normal file
52
projects/template-sync-strategy/canons/reference/glossary.md
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
title: Глоссарий
|
||||
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`.
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: Troubleshooting
|
||||
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
|
||||
```
|
||||
119
projects/template-sync-strategy/canons/setup/clean-repository.md
Normal file
119
projects/template-sync-strategy/canons/setup/clean-repository.md
Normal file
@@ -0,0 +1,119 @@
|
||||
---
|
||||
title: Новый проект от шаблона
|
||||
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).
|
||||
@@ -0,0 +1,144 @@
|
||||
---
|
||||
title: Миграция существующего master
|
||||
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).
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: Решение конфликтов
|
||||
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
|
||||
```
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
title: Review и merge
|
||||
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
|
||||
```
|
||||
@@ -0,0 +1,111 @@
|
||||
---
|
||||
title: Обычное обновление шаблона
|
||||
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).
|
||||
Reference in New Issue
Block a user