Обычный git rebase main молча применяет коммиты один за другим
в исходном порядке. Interactive (-i) даёт shell-меню над
коммитами.
Запуск
git rebase -i main # все коммиты текущей ветки от main
git rebase -i HEAD~5 # последние 5 коммитов
git rebase -i <sha> # коммиты после указанного 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, если тесты упадут. Удобно для проверки атомарности.