Пример 1. Инициализация в репозитории
Заходим в обычный Git-репозиторий и включаем Graphite. Он спросит, какая ветка — trunk.
# находимся в учебном репозитории (обычный git-репо)
cd ~/learning_git
gt init
# ? Select a trunk branch: main
# ✓ Graphite initialized. Trunk set to "main".
# авторизация для работы с PR на GitHub
gt auth -t ghp_xxxxxxxxxxxxxxxxxxxx
Пример 2. Собираем стек из трёх веток
Каждая команда gt create кладёт новый «этаж» поверх текущей ветки. Флаг -a застейджит все изменения, -m задаёт сообщение коммита.
# этаж 1 — поверх main
echo "model" > model.txt
gt create feat/tasks-model -a -m "feat: add Task model"
# этаж 2 — поверх feat/tasks-model
echo "service" > service.txt
gt create feat/tasks-service -a -m "feat: add task service"
# этаж 3 — поверх feat/tasks-service
echo "api" > api.txt
gt create feat/tasks-api -a -m "feat: add tasks API"
Смотрим стек целиком:
gt log short
# ◉ feat/tasks-api (current)
# ◯ feat/tasks-service
# ◯ feat/tasks-model
# ◯ main (trunk)
feat/tasks-api, в самом низу — main. Каждая ветка стоит на предыдущей.
Пример 3. Правим низ стека — весь стек обновляется сам
Ревьюер попросил переименовать поле в модели. Спускаемся в самый низ, правим, делаем gt modify — Graphite сам перебазирует service и api на исправленную модель.
gt bottom # переключились на feat/tasks-model
# ...правим model.txt...
echo "model v2" > model.txt
gt modify -a # amend коммита + АВТО-restack веток выше
# ✓ Restacked feat/tasks-service
# ✓ Restacked feat/tasks-api
git switch feat/tasks-service && git rebase feat/tasks-model, потом то же для feat/tasks-api. gt modify сделал это одной командой.
Пример 4. Отправляем стек на GitHub
Одна команда пушит все ветки стека и открывает (или обновляет) PR для каждой, корректно проставляя базовую ветку: PR #2 нацелен на ветку PR #1, а не на main.
gt submit --stack # короткий алиас: gt ss
# ✓ feat/tasks-model → PR #1 (base: main)
# ✓ feat/tasks-service → PR #2 (base: feat/tasks-model)
# ✓ feat/tasks-api → PR #3 (base: feat/tasks-service)
Пример 5. Нижний PR влили — синхронизируемся
Коллеги приняли PR #1. Запускаем gt sync: Graphite подтянет свежий main (уже с влитой моделью), перебазирует оставшийся стек и предложит удалить локальную ветку влитого PR.
gt sync
# ✓ Pulled main (1 PR merged)
# ? Delete merged branch feat/tasks-model? (Y/n) Y
# ✓ Restacked feat/tasks-service onto main
# ✓ Restacked feat/tasks-api
Пример 6. Конфликт во время restack
Если при перестроении возникает конфликт слияния, Graphite останавливается — разрешаем как обычно и продолжаем.
gt sync
# CONFLICT in service.txt
# ...правим конфликт в редакторе...
git add service.txt
gt continue # продолжить прерванную операцию
# или: gt abort — откатить всё к состоянию до операции
gt --help.