Rebase — это операция в Git, которая переносит коммиты из одной ветки на вершину другой, создавая линейную историю без лишних merge-коммитов. В отличие от слияния, rebase переписывает историю: каждый перенесённый коммит получает новый хеш, поскольку изменяется его родитель. По данным документации Git (2026), rebase применяется для синхронизации feature-веток с актуальным состоянием main перед созданием pull request. Команда git rebase — один из основных инструментов для поддержания чистой истории в проектах, использующих Git Flow.
Главное
Rebase — это команда Git, которая перебазирует текущую ветку на указанную: берёт все коммиты текущей ветки, временно сохраняет их, перемещает указатель ветки на целевой коммит и последовательно применяет сохранённые коммиты поверх него. Результат — история выглядит так, будто разработчик вёл работу непосредственно от последнего коммита целевой ветки.
Основной синтаксис: git rebase main — находясь в feature-ветке, эта команда переносит все коммиты feature на вершину main. Git использует стратегию three-way merge для каждого коммита отдельно. Если коммит A уже присутствует в целевой ветке (определяется по хешу), Git автоматически пропускает его, что позволяет избежать дублирования изменений.
Rebase также поддерживает onto-режим для переноса части коммитов: git rebase --onto target start end — эта форма позволяет извлечь диапазон коммитов из одной ветки и применить их поверх другой. Например, git rebase --onto main feature~3 feature перенесёт последние три коммита ветки feature поверх main.
# Switch to feature branch
git checkout feature
# Rebase feature onto main
git rebase main
# After successful rebase — history is linear
git log --oneline --graph
# Move last 3 commits to main
git rebase --onto main HEAD~3 HEAD
Rebase и merge решают одну задачу — объединение изменений из разных веток — но делают это принципиально разными способами. Merge сохраняет полную историю слияний, создавая merge-коммит с двумя родителями. Rebase переписывает историю, делая её линейной. Выбор между ними зависит от workflow команды и правил работы с репозиторием.
Основное различие — как фиксируется факт слияния. Merge сохраняет: «в этой точке мы объединили feature в main» — это информативно для истории проекта, но засоряет лог при частых слияниях. Rebase показывает: «коммиты feature были сделаны последовательно от последнего состояния main» — это чисто, но скрывает тот факт, что разработка велась параллельно.
Второе отличие — обработка конфликтов. При merge конфликты разрешаются один раз, и решение фиксируется в merge-коммите. При rebase конфликты могут возникнуть для каждого переносимого коммита, и каждый требует отдельного разрешения. Это более трудоёмко, но позволяет точнее контролировать, какие изменения попадают в итоговую версию.
| Критерий | Rebase | Merge |
|---|---|---|
| История | Линейная, без merge-коммитов | Нелинейная, с merge-коммитами |
| Хеши коммитов | Перезаписываются (новые) | Сохраняются оригинальные |
| Конфликты | Для каждого коммита отдельно | Один раз в merge-коммите |
| Публичные ветки | Запрещён | Разрешён |
| Команда отмены | git rebase --abort | git merge --abort |
Интерактивный rebase (git rebase -i) — это режим, при котором Git открывает редактор со списком коммитов и доступными действиями для каждого из них. Разработчик может переписать historю перед отправкой в удалённый репозиторий. Это основной инструмент для поддержания чистоты коммитов в feature-ветке.
Доступные команды в интерактивном режиме: pick (оставить коммит как есть), reword (изменить сообщение коммита), edit (остановиться для изменений), squash (объединить с предыдущим коммитом, сохранив оба сообщения), fixup (объединить, отбросив сообщение), drop (удалить коммит). Каждая команда указывается перед хешем коммита в открывшемся редакторе.
Squash и fixup — наиболее часто используемые команды для объединения коммитов. Если разработчик сделал 5 мелких коммитов с правками в процессе работы, squash объединит их в один логический коммит с осмысленным сообщением. Fixup полезен для исправления опечаток: изменения попадают в предыдущий коммит без сохранения своего сообщения.
# Open editor for last 4 commits
git rebase -i HEAD~4
# Editor will show:
pick a1b2c3d Add authentication
pick e4f5g6h Fix typo in login
squash i6j7k8l Additional login fixes
pick m9n0o1p Add auth tests
# After saving — Git performs rebase
# and opens editor for squashed commit message
# Auto-squash without opening editor
git rebase -i HEAD~4 --autosquash
Флаг --autosquash автоматически расставляет fixup/squash для коммитов, сообщения которых начинаются с fixup! или squash!. Это ускоряет работу, если разработчик заранее маркирует коммиты для последующего объединения. Флаг --committer-date-is-author-date сохраняет оригинальную дату коммита при перебазировании — полезно для сохранения временной хронологии в истории.
Конфликты при rebase возникают, когда Git не может автоматически применить переносимый коммит из-за противоречий с изменениями в целевой ветке. В отличие от merge, где конфликт разрешается один раз, при rebase каждый коммит может вызвать конфликт, и его нужно разрешать последовательно для каждого коммита от самого старого к самому новому.
Когда возникает конфликт, Git приостанавливает rebase и сообщает, какой коммит вызвал проблему. Разработчик открывает конфликтующий файл (Git маркирует конфликтные участки маркерами <<<<<<<, =======, >>>>>>>), редактирует его, добавляет в индекс (git add) и продолжает rebase командой git rebase --continue. Если решение не найдено — git rebase --abort полностью отменяет перебазирование.
Совет: при множественных конфликтах эффективнее использовать git mergetool, который открывает визуальный редактор для разрешения противоречий. Также можно пропустить проблемный коммит (git rebase --skip), но это удалит его изменения из итоговой истории, что редко бывает правильным решением.
# Start rebase with conflict
git rebase main
# Auto-merging file.txt
# CONFLICT (content): Merge conflict in file.txt
# Check status
git status
# both modified: file.txt
# Edit conflicted sections → git add → continue
git add file.txt
git rebase --continue
# If uncertain — abort
git rebase --abort
Золотое правило rebase: никогда не перебазировать коммиты, которые уже были отправлены в удалённый репозиторий и доступны другим разработчикам. Поскольку rebase перезаписывает хеши коммитов, у коллег возникнут конфликты при попытке синхронизации — их локальная история будет расходиться с переписанной удалённой.
Ситуация, в которой rebase категорически запрещён: если кто-то уже создал ветку на основе ваших коммитов (например, ваш коллега сделал feature от вашей feature), изменение истории сломает его работу. В таких случаях следует использовать merge. Также не рекомендуется делать rebase прямо перед дедлайном — ошибка при разрешении конфликтов может занять больше времени, чем ожидалось, и заблокировать релиз.
Исключение: если ветка используется только одним разработчиком (личная feature-ветка, не опубликованная или опубликованная в draft-режиме), rebase до пуша — стандартная практика. После публикации и начала коллективной работы — только merge. GitHub и GitLab по умолчанию предлагают squash merge как компромисс: он объединяет коммиты в один, но не перезаписывает историю целевой ветки.
В современных командах чаще всего используется rebase-ориентированный workflow в сочетании с GitHub Flow. Процесс выглядит так: разработчик создаёт feature-ветку от main, работает в ней, периодически синхронизируется через git rebase main, а перед созданием pull request выполняет интерактивный rebase для очистки истории.
После создания PR (если нужно подтянуть новые изменения из main) используется git pull --rebase main вместо обычного git pull. Это позволяет втянуть изменения без создания лишнего merge-коммита. Git pull с флагом --rebase эквивалентен git fetch + git rebase — Git сначала загружает новые коммиты, затем перебазирует локальные изменения поверх них.
Git позволяет настроить rebase как поведение по умолчанию для pull: git config --global pull.rebase true. После этой настройки git pull всегда выполняет rebase вместо merge. Если нужно выполнить обычный pull — используется git pull --no-rebase. Многие команды также включают autostash: git config --global rebase.autoStash true — это автоматически прячет незакоммиченные изменения перед rebase и восстанавливает их после.
Часто задаваемые вопросы
Отребейзить — значит выполнить git rebase: перенести коммиты текущей ветки на вершину другой. В результате история становится линейной, каждый коммит получает новый хеш, а merge-коммиты не создаются. Команда используется для синхронизации веток без лишних точек слияния в логе.
Merge создаёт merge-коммит с двумя родителями, сохраняя параллельную историю и оригинальные хеши. Rebase перезаписывает историю — коммиты получают новые хеши, а история становится линейной. Merge безопаснее для публичных веток, rebase даёт более чистый лог.
Команда git rebase -i HEAD~N открывает редактор с N последними коммитами. Для каждого коммита можно выбрать действие: pick (оставить), reword (переименовать), edit (изменить), squash (объединить с предыдущим), fixup (объединить без сообщения), drop (удалить). После сохранения Git применяет выбранные изменения.
Rebase перезаписывает хеши коммитов, что делает историю несовместимой с копиями тех же коммитов у других разработчиков. Если коллега уже получил ваши коммиты через git pull, а вы потом перебазировали их, его git push будет отклонён, а git pull создаст дублирующиеся коммиты и конфликты.
До завершения — git rebase --abort отменяет полностью. После завершения можно восстановить предыдущее состояние через git reflog — найти хеш коммита до rebase и выполнить git reset --hard к нему. Reflog хранит историю перемещений HEAD в течение 30 дней по умолчанию.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также