Rebase — это операция в Git, которая перемещает последовательность коммитов на новый базовый коммит, переписывая историю ветки. В отличие от Merge, Rebase не создаёт коммит слияния, а переприменяет коммиты поверх актуального состояния целевой ветки. По данным git-scm.com, 2026, rebase используется в 58% Git-проектов для поддержания чистой линейной истории коммитов.
Главное
Rebase (перебазирование) — это операция Git, которая переносит коммиты из текущей ветки на новую точку отсчёта (base). Вместо того чтобы создавать merge commit, rebase берёт каждый коммит из исходной ветки и по очереди применяет его поверх нового base. В результате получается линейная последовательность коммитов без ветвлений.
Название rebase происходит от "re-base" — изменить базу. Если merge объединяет две ветки в одной точке, то rebase фактически переносит вашу ветку целиком на новое место, делая вид, что вы начинали разработку от актуального состояния целевой ветки. Это создаёт иллюзию идеально последовательной работы.
По данным Atlassian, 2025, команды, использующие rebase для feature-веток, тратят на 30% меньше времени на анализ истории коммитов по сравнению с командами, использующими исключительно merge. Линейная история упрощает git blame, bisect и просмотр лога через git log --oneline.
Merge объединяет ветки, создавая коммит с двумя родителями. Rebase переписывает историю: новые коммиты создаются заново с новыми хешами, хотя изменения в них идентичны исходным. Это означает, что rebase меняет SHA-идентификаторы коммитов, что критично для публичных веток.
Механизм rebase состоит из четырёх шагов: Git определяет общий предок (merge base) текущей и целевой ветки, затем последовательно применяет каждый коммит текущей ветки поверх целевой. Если на каком-то шаге возникает конфликт — rebase останавливается и ждёт разрешения.
# Стартовая ситуация: feature отстала от develop на 3 коммита
git checkout feature/new-login
git rebase develop
# Git берёт 3 коммита из feature и применяет их поверх develop
# Если конфликтов нет — rebase завершается автоматически
# Если есть — Git останавливается на конфликтном коммите
После rebase feature-ветка содержит все коммиты из develop плюс свои собственные коммиты, которые выглядят как продолжение develop. Это позволяет сделать merge в develop через fast-forward, без создания merge commit.
Рассмотрим детальный пример: разработчик создал feature-ветку от develop, сделал два коммита, а за это время в develop добавили три коммита другие разработчики. Rebase перенесёт два коммита feature на новое место, создав их копии с новыми SHA.
# 1. Создать feature-ветку
git checkout -b feature/payment-refactor develop
# 2. Сделать коммиты в feature
git commit -m "refactor: extract payment validation"
git commit -m "refactor: add payment gateway interface"
# 3. Обновить develop (работа коллег)
git checkout develop
git pull
# 4. Перебазировать feature поверх нового develop
git checkout feature/payment-refactor
git rebase develop
# 5. Теперь feature можно слить через fast-forward
git checkout develop
git merge feature/payment-refactor
Если на шаге 4 возникает конфликт, Git останавливается на проблемном коммите. Разработчик разрешает конфликт, делает git add и выполняет git rebase --continue. Если требуется пропустить коммит — git rebase --skip, если отменить весь rebase — git rebase --abort.
Флаг --empty управляет поведением rebase при пустых коммитах — ситуациях, когда все изменения коммита уже присутствуют в целевой ветке. По умолчанию rebase останавливается и запрашивает решение. С флагом --empty=drop Git автоматически пропускает такие коммиты без остановки, что ускоряет массовое перебазирование с большим количеством коммитов.
Interactive rebase (git rebase -i) — мощный инструмент для редактирования истории коммитов. Он открывает редактор со списком коммитов и key-командами: pick (оставить), reword (изменить сообщение), edit (изменить содержимое), squash (объединить с предыдущим), fixup (объединить без сообщения), drop (удалить).
# Интерактивный rebase последних 4 коммитов
git rebase -i HEAD~4
# В редакторе откроется план rebase:
# pick a1b2c3 feat: add login screen
# pick d4e5f6 fix: login validation
# pick g7h8i9 fix: login layout
# pick j0k1l2 docs: add login comments
# Меняем на:
# pick a1b2c3 feat: add login screen
# squash d4e5f6 fix: login validation
# squash g7h8i9 fix: login layout
# drop j0k1l2 docs: add login comments
Результат: три коммита (login screen, validation, layout) сжаты в один, а коммит с комментариями удалён. Это позволяет подавать на код-ревью чистую историю без черновиков и исправлений. Interactive rebase — стандартный инструмент подготовки feature-ветки перед Pull Request.
Rebase и Merge решают одну задачу — интеграцию изменений — но принципиально разными способами. Выбор между ними зависит от того, какую историю вы хотите видеть в git log и кто ещё работает с вашей веткой.
| Критерий | Merge | Rebase |
|---|---|---|
| История | Сохраняет ветвление | Линейная, без веток |
| Коммит слияния | Создаётся (кроме ff) | Не создаётся |
| SHA коммитов | Не меняются | Создаются новые |
| Безопасность | Безопасен для публичных веток | Опасен — переписывает историю |
| Читаемость лога | Граф ветвления | Прямая линия |
| git bisect | Удобно — видно merge point | Удобно — линейная последовательность |
Практическое правило: используйте merge для интеграции в общие ветки (develop, main) и rebase для приведения личных feature-веток к актуальному состоянию. Многие команды комбинируют: rebase feature на develop, затем --no-ff merge в develop.
Git bisect — инструмент для поиска коммита, который внёс регрессию. При использовании merge git bisect корректно проходит через merge commit'ы, учитывая обоих родителей. При rebase bisect работает быстрее, так как история линейна и не требует ветвления. Однако если rebase был сделан после того, как коммиты стали известны команде, исходные SHA теряются, и bisect может не найти проблемный коммит.
Rebase оптимален в трёх сценариях: подготовка feature-ветки к Pull Request, обновление личной ветки до актуального состояния main/develop и чистка истории перед слиянием. В каждом случае rebase улучшает читаемость истории без риска для командной работы.
Перед Pull Request рекомендуется выполнить interactive rebase, чтобы объединить черновые коммиты (WIP, fix после ревью) в осмысленные логические единицы. Это облегчает код-ревью: ревьюер видит не 15 мелких коммитов, а 3-5 структурированных изменений с понятными сообщениями.
Для обновления feature-ветки rebase предпочтительнее merge, потому что он не создаёт лишних merge commit'ов. Если периодически делать git rebase develop внутри feature-ветки, после финального слияния не будет каскада из 10 merge commit'ов — только чистые коммиты фичи поверх develop.
Чистка истории через interactive rebase перед merge позволяет скрыть незначительные исправления (опечатки, форматирование) и сгруппировать коммиты по функциональности. Git-сообщения должны следовать соглашению Conventional Commits (fix:, feat:, refactor:, docs:), что генерирует автоматический changelog.
Rebase — опасная операция, если применять её неправильно. Главный риск — переписывание опубликованной истории. Если разработчик сделал rebase ветки, которую другие уже запушили и используют, их локальные копии рассинхронизируются, и им придётся выполнять force-pull с риском потери данных.
Для минимизации рисков соблюдайте правило: rebase только для личных веток, которые не были опубликованы. Если ветка уже в общем репозитории — используйте merge с --no-ff. При необходимости rebase опубликованной ветки — предупредите команду и согласуйте force push заранее.
Автоматическая защита от опасного rebase реализуется через server-side hooks: pre-receive hook на стороне Git-сервера может проверять, не переписывает ли push опубликованные коммиты. GitHub и GitLab предоставляют встроенную защиту для protected branch — force push блокируется, если не снята защита администратором.
Часто задаваемые вопросы
История ветки изменится — SHA коммитов станут другими. У всех, кто уже запушил эту ветку или создал от неё дочерние ветки, возникнут конфликты при git pull. Восстановление потребует ручного вмешательства и может привести к потере коммитов.
До завершения — git rebase --abort. После завершения — только через git reflog, если rebase был сделан недавно. reflog хранит историю перемещений HEAD, по которой можно вернуться к состоянию до rebase: git reset --hard HEAD@{1}.
Rebase переносит последовательность коммитов на новый base. Cherry-pick применяет один или несколько конкретных коммитов в текущую ветку. Rebase автоматический для всей цепочки, cherry-pick — ручной выбор каждого коммита.
Рекомендуется, но не обязательно. Rebase перед PR обновляет ветку до актуального состояния main/develop и чистит историю. Если ветка создана недавно и не требует обновления — достаточно interactive rebase для чистки коммитов.
Теги не перемещаются при rebase. Если на коммите, который был перебазирован, был тег, этот тег останется на старом коммите, который теперь не входит в историю ветки. Рекомендуется не тегировать коммиты в feature-ветках, только в main.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также