# Interactive rebase
_Ветки и слияния · GitLab Knowledge Base_
**TL;DR:** `git rebase -i ` открывает редактор со списком коммитов от
`` до HEAD, где можно переименовывать, объединять, удалять и
переставлять их. Главный инструмент для очистки локальной истории.
Обычный `git rebase main` молча применяет коммиты один за другим
в исходном порядке. Interactive (`-i`) даёт shell-меню над
коммитами.
## Запуск
```bash
git rebase -i main # все коммиты текущей ветки от main
git rebase -i HEAD~5 # последние 5 коммитов
git rebase -i # коммиты после указанного sha
```
Откроется редактор:
```
pick a1b2c3d add login form skeleton
pick d4e5f6a fix typo
pick 7a8b9c0 wire up backend
pick b1c2d3e address review comments
pick f4e5d6c another fix
# Команды:
# p, pick = использовать коммит
# r, reword = использовать, поменять сообщение
# e, edit = использовать, остановиться для правки
# s, squash = слить с предыдущим (объединить сообщения)
# f, fixup = слить с предыдущим, отбросить сообщение
# d, drop = удалить коммит
# x = выполнить shell-команду
# b, break = остановиться (как edit, без правки коммита)
```
Меняешь `pick` на нужную команду, сохраняешь, выходишь. Git
переиграет историю по новой инструкции.
## Самое частое
**Squash «процессуального шума» перед PR.**
```
pick a1b2c3d feat: add login form
squash d4e5f6a fix typo
squash 7a8b9c0 wire up backend
```
Три коммита станут одним «feat: add login form» с объединёнными
правками. Git предложит отредактировать общее сообщение.
**Fixup без редактирования сообщения.**
Аналогично `squash`, но не открывает редактор сообщений -
использует сообщение первого коммита, отбрасывает остальные.
```
pick a1b2c3d feat: add login form
fixup d4e5f6a fix typo
```
**Reword.**
Поправить сообщение коммита, который уже не последний (для
последнего достаточно `git commit --amend`).
```
reword a1b2c3d add login form skeleton
pick d4e5f6a real change
```
**Drop.**
Удалить случайный коммит (debug-print, временный TODO).
```
pick a1b2c3d feat: add login form
drop d4e5f6a console.log everywhere
pick 7a8b9c0 real next change
```
**Перестановка.**
Если порядок коммитов нелогичен - просто переставь строки в
редакторе. Git применит в новом порядке (если правки совместимы).
## После interactive rebase
Локальная история переписана, у коммитов новые SHA. Если ветка
запушена - нужен `push --force-with-lease`.
## Подводные камни
- **Не делать на публичных ветках.** Переписанная история ломает
всех, кто склонил старую версию.
- **Перестановка может привести к конфликтам.** Если второй коммит
зависит от первого, а ты ставишь его первым - будет конфликт,
придётся разрешать.
- **`drop` удаляет, не откатывает.** Если нужно публично откатить
коммит, используй `git revert`. `drop` удаляет коммит из
истории, как будто его не было.
- **`x` - мощный, но рискованный.** `x` запускает shell-команду
после применения коммита. Например `x make test` - остановит
rebase, если тесты упадут. Удобно для проверки атомарности.
## Команды
```bash
git rebase -i HEAD~5
```
Открыть меню для последних 5 коммитов
```bash
git rebase -i --autosquash
```
Авто-расставить fixup для коммитов вида `fixup! `
```bash
git commit --fixup=
```
Создать коммит, предназначенный для fixup в будущем rebase
## См. также
- [git rebase](/courses/git/kb/rebase.md)
- [git commit --amend](/courses/git/kb/amend.md)
- [git cherry-pick](/courses/git/kb/cherry-pick.md)