Введение
Эта статья объясняет, что такое перебазирование в Git, как его выполнять, когда оно полезно и какие проблемы могут возникнуть. Вы узнаете, как использовать git rebase для создания чистой истории коммитов и как избежать проблем при работе с публичными репозиториями. Примеры подходят для любой операционной системы с установленным Git.
Простейшее перебазирование
Перебазирование — это альтернатива слиянию для интеграции изменений из одной ветки в другую. Вместо создания коммита слияния оно переносит коммиты одной ветки поверх другой, создавая линейную историю.
Пример: у вас есть две ветки, master и experiment, с разделённой историей. Чтобы перебазировать experiment на master:
git checkout experiment
git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command Процесс:
- Git находит общего родителя веток (
masterиexperiment). - Сохраняет изменения из
experimentво временные файлы. - Перемещает
experimentна последний коммитmaster. - Применяет сохранённые изменения по порядку.
Затем выполните перемотку master:
git checkout master
git merge experiment Результат идентичен трёхстороннему слиянию, но история выглядит линейной, как будто все изменения делались последовательно.
Более сложное перебазирование
Перебазирование позволяет переносить изменения между ветками, даже если они ответвлены от других тематических веток. Пример: у вас есть ветка server с серверными изменениями и ветка client, ответвлённая от server, с клиентскими изменениями.
Чтобы перенести только клиентские изменения (client) на master, исключив серверные:
git rebase --onto master server client Это переносит коммиты из client, не входящие в server, на master. Затем выполните перемотку:
git checkout master
git merge client Для переноса изменений из server на master без переключения:
git rebase master server И завершите перемоткой:
git checkout master
git merge server Удалите ненужные ветки:
git branch -d client
git branch -d server Итоговая история будет линейной, включающей все изменения.
Опасности перебазирования
Предупреждение: Не перебазируйте коммиты, уже отправленные в публичный репозиторий.
Перебазирование переписывает историю, создавая новые коммиты вместо старых. Если другие разработчики используют эти коммиты, они столкнутся с проблемами при синхронизации.
Пример проблемы:
- Вы клонируете репозиторий и создаёте коммиты в ветке
feature. - Коллега отправляет перебазированные изменения с
git push --force, переписывая историюmaster. - При выполнении
git pullсоздаётся коммит слияния, дублирующий изменения, что приводит к путанице.
Решение: используйте git pull --rebase для синхронизации:
git pull --rebase Или вручную:
git fetch origin
git rebase origin/master Git использует patch-id для определения одинаковых изменений, что помогает избежать дублирования. Настройте git pull для автоматического перебазирования:
git config --global pull.rebase true Перебазирование vs. Слияние
Слияние создаёт коммит слияния, сохраняя историю разветвлений. Перебазирование делает историю линейной, но переписывает коммиты.
Две точки зрения на историю:
- Историческая точность: История коммитов — это документ, отражающий реальные события. Переписывание считается нежелательным.
- Чистая история: История — это рассказ о создании проекта, который должен быть отредактирован для ясности, как книга.
Выбор зависит от проекта:
- Используйте перебазирование для локальных изменений перед отправкой в публичный репозиторий, чтобы сохранить чистую историю.
- Используйте слияние для сохранения реальной истории или при работе с уже опубликованными коммитами.
Заключение
Перебазирование в Git — мощный инструмент для создания линейной истории коммитов, особенно полезный для локальной работы или подготовки изменений для внешних проектов. Однако его использование с публичными коммитами может вызвать проблемы. Используйте git rebase для локальных веток и git merge для сохранения истории в командной работе.
Отзывы