Rebase и merge решают одну задачу — влить изменения из одной ветки в другую, — но по-разному обходятся с историей. Споры о том, что лучше, ведутся годами, хотя ответ зависит от ситуации. Разберём разницу, типичные ошибки и, главное, как вернуть всё назад, если rebase пошёл не туда.

В чём принципиальная разница

Merge безопасен и сохраняет всю историю как есть: он создаёт коммит слияния, и в дереве видно точку соединения и все промежуточные коммиты. Rebase, наоборот, переносит ваши коммиты на вершину целевой ветки и делает историю линейной. Это две философии:

  • Merge показывает, как всё было на самом деле, со всеми ответвлениями.
  • Rebase переписывает историю в чистую прямую линию, как будто работа велась последовательно.

Squash: когда нужен один аккуратный коммит

Отдельный вариант — squash-merge, который схлопывает пачку коммитов в один. Он ставит во главу угла чистоту целевой ветки: вместо двадцати промежуточных коммитов с правками опечаток в main попадает один осмысленный. Rebase же ценит линейность и гибкость, позволяя переписать историю и аккуратно вписать чужие изменения.

Интерактивный rebase: уборка перед слиянием

Интерактивный rebase даёт полный контроль над коммитами при переносе: можно объединять, переписывать сообщения и менять порядок. Обычно так наводят порядок в ветке перед вливанием в main. Для большинства команд лучше всего работает связка: интерактивным rebase чистят коммиты внутри ветки, а в main вливают через squash, чтобы основная история оставалась лаконичной.

Золотое правило rebase

Главная опасность rebase — переписывание истории. Если нарушить золотое правило и сделать rebase ветки, которую вы уже отправили на сервер и которой пользуются коллеги, вы перепишете общую историю, и локальные копии других разработчиков сломаются. Правило простое: rebase делают только на своих локальных, ещё не расшаренных коммитах. Публичную историю не трогают.

Если что-то сломалось: восстановление