В чем разница между git merge и git rebase?

Ответ

git merge и git rebase — это два разных подхода к интеграции изменений из одной ветки в другую, каждый со своей философией работы с историей.

Визуальное отличие

До операции:

main:     A---B---C
feature:       D---E

После git merge:

main:     A---B---C---F
                      
feature:       D---E---/
# F — merge-коммит, объединяющий C и E

После git rebase feature на main:

main:     A---B---C
feature:           D'---E'
# D и E переписаны как D' и E', будто были сделаны после C

Практические примеры

# Способ 1: Merge (сохраняет историю как есть)
git checkout main
git merge feature
# Создается merge-коммит с сообщением по умолчанию

# Способ 2: Rebase (переписывает историю)
git checkout feature
git rebase main
# Коммиты feature теперь идут после коммитов main
git checkout main
git merge feature  # Теперь это fast-forward merge

Сравнение подходов

Аспект git merge git rebase
История Сохраняет полную историю с merge-коммитами Создает линейную историю без merge-коммитов
Безопасность Не изменяет существующие коммиты Переписывает историю (меняет хеши коммитов)
Сложность Проще, меньше рисков Требует понимания, может вызвать конфликты
Идеально для Публичных веток (main, develop) Локальных веток перед интеграцией

Когда что использовать

Используйте git merge когда:

  • Работаете с общей/публичной веткой
  • Важна точная история всех изменений
  • Не хотите рисковать переписыванием истории
  • Интегрируете завершенные фичи

Используйте git rebase когда:

  • Работаете в локальной ветке
  • Хотите чистую линейную историю
  • Нужно интегрировать изменения из основной ветки
  • Готовы разрешать конфликты последовательно

⚠️ Критически важное правило

Никогда не делайте rebase коммитов, которые уже были отправлены в общий репозиторий! Это изменит историю для всех участников и вызовет серьезные проблемы с синхронизацией.

# ОПАСНО: если коммиты уже были отправлены
git push origin feature  # Отправили коммиты D и E
git rebase main          # Переписали историю → D' и E'
git push --force         # Принудительная отправка → проблемы у коллег

Ответ 18+ 🔞

А, слушай, вот эта тема про git merge и git rebase — это ж классический разговор на кухне любого разработчика, где каждый второй считает себя гуру, а на деле все путают. Ёпта, давай разложу по полочкам, чтобы даже кот этот, сука, собака, понял.

Представь, есть у тебя главная дорога — ветка main. И есть твоя кривая тропинка — ветка feature, где ты накосячил кучу коммитов. Так вот, как эту тропинку к дороге приделать?

Картинка для тех, кто в танке

Было так:

main:     A---B---C
feature:       D---E

Твои коммиты D и E ответвились от B и идут параллельно.

Если сделаешь git merge (по-стариковски):

main:     A---B---C---F
                      
feature:       D---E---/

Появится новый коммит-уродец F (мерж-коммит), который просто кричит: "Смотрите, я тут две хуйни склеил!". История сохраняется, но выглядит как ёлка, которую кот обоссал.

А если сделаешь git rebase (по-модному):

main:     A---B---C
feature:           D'---E'

Вот тут магия, блядь! Git берет твои коммиты D и E, отрывает их от старого места и заново прилепляет поверх актуального main, как будто ты их только что и сделал. Они даже имена меняют на D' и E' — новые хеши, всё по-новой. История становится прямой, как палка, без лишних развилок. Красота, да? Но, сука, подвох есть.

Как это на практике выглядит

# Способ для ленивых и осторожных — MERGE
git checkout main
git merge feature
# Готово. Появился коммит-свинота, который всех объединил. Спать спокойно.

# Способ для чистюль и мазохистов — REBASE
git checkout feature
git rebase main
# Сидишь и по одному разрешаешь конфликты для каждого своего старого коммита. Веселье.
git checkout main
git merge feature # А тут уже мерж быстрый, прямолинейный, без лишнего коммита.

Так что же выбрать? Сравнительная таблица, блядь

Что смотрим git merge (старая школа) git rebase (хипстерский способ)
История коммитов Реалистичная, как жизнь — запутанная и с развилками. Идеальная, линейная, как из учебника. Небывалая хуйня.
Безопасность Почти нулевой риск. Ничего не переписываешь. ОПАСНОСТЬ, ЁПТА! История меняется, коммиты перерождаются.
Сложность Попроще. Нажал — получил мерж-коммит. Посложнее. Надо понимать, что делаешь, и любить решать конфликты по 5 раз.
Для чего создан Для публичных, общих веток (main, develop). Для своей локальной ветки, пока ты её не отправил на сервер и не опозорился.

Главное правило, которое нарушают все

ЁБАНЫЙ В РОТ, НИКОГДА НЕ ДЕЛАЙ REBASE ТОГО, ЧТО УЖЕ ОТПРАВИЛ В ОБЩИЙ РЕПОЗИТОРИЙ!

Представь картину:

git push origin feature  # Отправил свои коммиты D и E. Коллеги их уже стянули.
git rebase main          # Переписал историю, получил D' и E'. У тебя теперь всё чисто.
git push --force         # БАБАХ! Ты перезаписал историю на сервере.

А твой коллега Вася приходит на работу, делает git pull и у него всё ебётся, потому что его локальные коммиты D и E уже не совпадают с твоими новыми D' и E'. Он тебе такого пожелает, что мало не покажется. Это пиздец, доверия ебать ноль после такого.

Короткий итог, чтобы не ебать мозг

  • git merge — когда работаешь с общей веткой или тебе похуй на идеальную историю. Безопасно и предсказуемо.
  • git rebase — когда прибираешься в своей локальной ветке перед тем, как влить её в основную. Делает историю красивой, но требует ума и ответственности.

Выбирай по ситуации. А то некоторые так увлекаются этим ребейзом, что потом сами от себя охуевают, когда всё ломается.