Git rebase: как работает, rebase onto и интерактивный режим
Git rebase переносит коммиты вашей ветки на новую базу, например на свежий main, и делает историю линейной. Базовый вариант: git rebase main из рабочей ветки. Команда переписывает коммиты, поэтому не применяйте её к веткам, которыми уже пользуются другие.
Обновить ветку поверх main
git switch feature/login
git fetch origin
git rebase origin/mainGit временно откладывает ваши коммиты, переключает ветку на origin/main и заново применяет коммиты один за другим. У них изменятся хеши, потому что у них новый родитель.
Если возник конфликт
Git остановится на конфликтном коммите. Исправьте файлы и продолжайте:
git add путь/к/файлу
git rebase --continue # перейти к следующему коммиту
git rebase --skip # отбросить текущий коммит целиком
git rebase --abort # отменить rebase и вернуть ветку как былоИнтерактивный режим: склеить и поправить коммиты
git rebase -i HEAD~4Git откроет список последних четырёх коммитов. Перед каждым стоит команда, её можно заменить:
Команда | Что делает |
|---|---|
| Оставить коммит как есть |
| Оставить, но изменить сообщение |
| Остановиться на коммите, чтобы изменить содержимое |
| Влить в предыдущий коммит и объединить сообщения |
| Влить в предыдущий коммит, сообщение выбросить |
| Удалить коммит |
Строки идут от старого коммита к новому. Меняйте порядок строк, чтобы поменять порядок коммитов.
Перенести часть ветки через --onto
Допустим, ветка feature/ui выросла из feature/api, а feature/api ещё не готова. Нужно перенести только коммиты feature/ui на main:
git rebase --onto main feature/api feature/uiЗапись читается так: «возьми коммиты после feature/api, которые есть в feature/ui, и поставь их поверх main».
Rebase при загрузке изменений
git pull --rebase # вместо merge-коммита перенести свои коммиты
git config --global pull.rebase true # делать так при каждом pullMerge или rebase
merge | rebase | |
|---|---|---|
История | Сохраняет ветвление и создаёт merge-коммит | Линейная, без лишних merge-коммитов |
Хеши коммитов | Не меняются | Меняются |
Общие ветки | Безопасен | Опасен: другие получат расходящуюся историю |
Как отменить rebase после завершения
git reflog # найдите запись до начала rebase
git reset --hard ORIG_HEAD # вернуть ветку к состоянию до rebaseORIG_HEAD хранит положение ветки перед последней опасной операцией, но следующая такая операция его перезапишет.
Частые вопросы
Можно ли сделать rebase ветки, которая уже на сервере?
Можно, если над ней работаете только вы. После rebase отправляйте ветку командой git push --force-with-lease.
Чем squash отличается от fixup?
Оба объединяют коммит с предыдущим. squash оставляет оба сообщения для редактирования, fixup оставляет только сообщение первого коммита.