Git: интерактивный rebase не так страшен, как он работает
Автор заметки разбирает страх перед командой git rebase -i и сводит её работу к понятной модели: команда git rebase -i HEAD~4 открывает текстовый файл с перечнем последних коммитов и инструкциями для каждого из них. До подтверждения изменений этот список является планом, а не уже выполненным преобразованием; если пользователь передумал, rebase можно отменить командой git rebase --abort.
В плане для каждого коммита можно оставить pick (взять как есть), поставить reword для изменения сообщения, squash для объединения с предыдущим коммитом, fixup для объединения без сохранения сообщения или drop для удаления. В примере автор меняет сообщение первого коммита, удаляет рабочий отладочный коммит, а два средних оставляет без изменений: в результате из четырёх коммитов остаётся три. Удалить коммит можно и просто убрав его строку из файла плана.
Заметка отдельно объясняет, почему ошибка при rebase обычно обратима. Rebase не редактирует старые коммиты, а создаёт новые и переносит на них указатель ветки; прежние объекты некоторое время сохраняются в базе Git. Историю положений указателя ветки можно посмотреть через git reflog, а затем вернуть состояние, например, git reset --hard HEAD@{4}. Для дополнительной страховки до начала работы предлагается создать ветку git branch backup-before-rebase и при необходимости вернуться к ней.
При конфликте Git останавливает rebase: нужно разрешить конфликт, добавить исправленные файлы командой git add, затем выполнить git rebase --continue. По мнению автора, такой конфликт может быть проще слияния, потому что приходится разбирать один коммит за раз. В качестве осторожного правила он советует свободно переписывать собственные функциональные ветки до или во время ревью и отправлять их с git push --force-with-lease, который откажется перезаписывать удалённую ветку, если её успел обновить кто-то другой. Главная цель текста, снять мистический ореол с интерактивного rebase и побудить начинающих разработчиков попробовать простой сценарий осознанно.
Ключевые факты
- git rebase -i HEAD~4 открывает файл-план с последними четырьмя коммитами; до выполнения его можно отменить через git rebase --abort.
- Инструкции pick, reword, squash, fixup и drop позволяют соответственно оставить коммит, изменить его сообщение, объединить его с предыдущим с сохранением или без сохранения сообщения и удалить его.
- Rebase создаёт новые коммиты и передвигает указатель ветки, поэтому предыдущее состояние обычно можно найти в git reflog и восстановить командой git reset --hard HEAD@{4}.
- Перед преобразованием можно создать ветку backup-before-rebase; конфликты решаются по одному коммиту с git add и git rebase --continue.
- Для отправки переписанной собственной ветки автор рекомендует git push --force-with-lease, а не обычный --force.
Почему это важно
Интерактивный rebase позволяет привести историю собственной ветки в порядок до слияния: переименовать коммит, убрать временный отладочный шаг или объединить несколько мелких изменений. Текст делает акцент на том, что пользователь сначала редактирует план действий, а не мгновенно и необратимо меняет историю.
Кому это важно
В первую очередь, начинающим разработчикам и тем, кто избегает git rebase -i из-за опасения потерять работу. Приём также относится к разработчикам, ведущим собственные функциональные ветки до или в ходе ревью.
Как это применить
Запустите, например, git rebase -i HEAD~4, отредактируйте строки плана: используйте reword для сообщения, squash или fixup для объединения, drop либо удаление строки для исключения коммита. При конфликте исправьте файлы, выполните git add и git rebase --continue; при отказе от операции, git rebase --abort. Перед началом можно создать резервную ветку git branch backup-before-rebase.
Можно ли доверять
Это практическая авторская заметка, а не официальная документация Git. Описанные команды и модель работы подкреплены конкретными примерами из текста, однако решение о том, когда переписывать историю, остаётся рабочим правилом автора.
Риски и подводные камни
Rebase требует понимать выполняемые действия: при перестановке коммитов или переносе на обновлённую основную ветку возможны конфликты. Не следует небрежно переписывать общую историю; совет автора относится к собственным веткам. Для отправки изменений используйте git push --force-with-lease, который не позволит перезаписать удалённую ветку, если её уже обновил другой человек. Если что-то пошло не так, воспользуйтесь git reflog или заранее созданной резервной веткой.
«Rebase не уничтожает коммиты, он создаёт новые.»
— Из заметки «Git rebase -I is not that scary»