Ответ
Обе команды интегрируют изменения из одной ветки в другую, но делают это принципиально разными способами, влияя на историю коммитов.
git merge
- Действие: Создает новый коммит слияния (merge commit), который имеет двух родителей. Этот коммит объединяет историю двух веток.
- История: Сохраняет нелинейную, полную историю разработки (видно ветвление и слияние).
- Безопасность: Не переписывает существующую историю, поэтому безопасна для публичных веток.
# Стандартное слияние feature в main
git checkout main # Переключиться на принимающую ветку
git merge feature # Объединить изменения из ветки feature
git rebase
- Действие: Перемещает (перебазирует) всю цепочку коммитов текущей ветки и «применяет» их поверх указанной ветки. Фактически переписывает историю, создавая новые коммиты с новыми хэшами.
- История: Делает историю линейной, как если бы работа велась последовательно в одной ветке. Убирает видимость параллельной разработки.
- Риск: Переписывает историю, что опасно для коммитов, уже отправленных в общий репозиторий (публичные ветки).
# Перебазирование feature на актуальный main
git checkout feature # Переключиться на ветку, которую перебазируем
git rebase main # «Перемотать» коммиты feature поверх main
Сравнение на диаграмме
До операции (ветка feature ответвилась от main):
A---B---C (main)
D---E (feature)
После git merge:
A---B---C---F (main)
/
D---E (feature)
Коммит F — это merge-коммит, объединяющий C и E.
После git rebase (и последующего fast-forward merge):
A---B---C---D'---E' (main)
Коммиты D' и E' — это новые коммиты с тем же содержанием, что D и E, но примененные поверх C.
Когда что использовать?
- Используйте
merge:- Для слияния публичных веток (например,
featureвmain). - Когда важно сохранить полный контекст и историю слияний.
- Для слияния публичных веток (например,
- Используйте
rebase:- Локально, чтобы поддерживать чистую линейную историю перед слиянием в основную ветку.
- Для обновления своей feature-ветки актуальными изменениями из
main(git rebase main). - Никогда не делайте
rebaseкоммитов, которые уже были отправлены в общий репозиторий.