# git rebase _Ветки и слияния · GitLab Knowledge Base_ **TL;DR:** Переписывает коммиты ветки, делая их потомками другого коммита. Создаёт новые SHA, история становится линейной. Безопасен только для веток, которые ещё никто, кроме автора, не видел. `git rebase ` берёт коммиты текущей ветки от общего предка с `` до HEAD и пересаживает их поверх ``. У каждого коммита меняется родитель → меняется SHA. ## Базовый сценарий ``` до: main: A → B → E \ feat: C → D git switch feat git rebase main после: main: A → B → E \ feat: C' → D' ← новые SHA ``` Логика правок в C' и D' та же, что в C и D. Но это другие объекты - для Git «новые коммиты». ## Когда применять - **Перед PR**, чтобы feature-ветка стояла на свежем main, без merge-коммитов. - **Очистить локальную историю** через `rebase -i` (см. [interactive-rebase](/courses/git/kb/interactive-rebase.md)). - **Переместить ветку** на другой базис через `--onto`. ## Главное правило **Не rebase'ить публичные ветки.** Если ветку кто-то склонил, у него останутся старые SHA. После твоего force-push возникает каша. Безопасно - только на личной feature до или сразу после ревью. ## Конфликты Если на каком-то коммите возникает конфликт - Git останавливается, показывает файлы с маркерами, ждёт разрешения: ```bash # править файлы, убирать маркеры git add git rebase --continue # продолжить со следующего коммита # или отказаться от текущего коммита: git rebase --skip # или отменить всё: git rebase --abort ``` Конфликт может возникать на каждом коммите подряд (если каждый трогает спорные строки). После rebase каждый промежуточный результат уже разрешён. ## После rebase Если ветка была запушена - обычный push откажет, потому что SHA поменялись: ```bash git push --force-with-lease ``` `--force-with-lease` проверяет, что remote не успел уйти вперёд (никто другой не запушил). Лучше всегда `--force-with-lease`, не `--force`. ## Подводные камни - Rebase копирует автор-даты коммитов как есть, но обновляет committer-даты. После rebase `git log --pretty=fuller` может показывать «странные» расхождения. - На большом количестве коммитов rebase может занять заметное время и потребовать разрешения конфликтов на каждом шаге. - `git pull --rebase` объединяет fetch с rebase'ом твоих локальных коммитов поверх удалённых. Удобно как дефолт: `git config --global pull.rebase true`. ## Команды ```bash git rebase main ``` Пересадить текущую ветку поверх main ```bash git rebase -i HEAD~5 ``` Interactive rebase: переименовать/сжать/удалить последние 5 коммитов ```bash git rebase --continue ``` Продолжить rebase после разрешения конфликта ```bash git rebase --abort ``` Отменить начатый rebase, вернуться в исходное состояние ## См. также - [git merge](/courses/git/kb/merge.md) - [Interactive rebase](/courses/git/kb/interactive-rebase.md) - [git cherry-pick](/courses/git/kb/cherry-pick.md)