Найти в Дзене

Merge vs Rebase

Оглавление

В гите есть несколько способов объединять веточки и подтягивать изменения. Посмотрим на самые популярные: Rebase и Merge.

Merge (Слияние)

Merge — это процесс объединения изменений из одной ветки с другой. Довольно часто разработчики используют именно его, чтобы в свою веточку подтянуть актуальный develop.

Когда мы делаем merge, Git создает новый коммит, который содержит изменения из обеих веток. Это создает некий "состыковочный" коммит, который объединяет изменения.

Например, если мы хотим подтянуть изменения с девелопа, то делаем git merge develop. И результат будет таким:

Тут мы видим, что у нас есть коммит в веточке. И когда мы сделали merge, то создался еще один коммит.

Плюсы Merge:

  1. Merge сохраняет оригинальную историю коммитов. Это полезно, если важна хронология изменений и контекст разработки.
  2. Merge реже вызывает конфликты, так как создает новый коммит, который объединяет изменения.

Минусы Merge:

  1. История коммитов может стать более сложной и менее читаемой из-за создания дополнительных "состыковочных" коммитов.
  2. Merge создает дополнительные коммиты для слияния, что может привести к более громоздкой истории.

Rebase (Перебазирование)

Rebase — это процесс перемещения всех коммитов текущей ветки поверх другой ветки. Это изменяет историю коммитов, делая ее более линейной. При rebase изменения из исходной ветки (текущей, где пишем код) применяются к целевой ветке (из которой хотим изменения) последовательно, как если бы они были сделаны в ней.

Например, если мы хотим подтянуть изменения с девелопа, то делаем git rebase develop. И результат будет таким:

-2

Тут видно, что наш коммит остался сверху, а изменения из девелопа все внизу. Как будто мы прямо сейчас создали ветку от актуального девелопа, а не сделали это полгода назад.

Плюсы Rebase:

  1. Одним из основных преимуществ rebase является создание линейной истории коммитов. Это делает историю проекта более читаемой и понятной.
  2. После rebase можно устранить конфликты и привести код в более чистое состояние, так как изменения применяются поочередно.

Минусы Rebase:

  1. Rebase изменяет историю коммитов и их хэш-коды, что может быть проблемой, если кто-то уже использовал старую версию исходной ветки. Поэтому советуют использовать rebase в тех случаях, когда разработчики не пересекаются в веточках и каждый пишет в своей.
  2. При rebase могут возникнуть конфликты, особенно если изменения были внесены в одни и те же строки кода в разных ветках. И тут конфликты более болезненные чем в merge (подробности ниже).

Выбор между Rebase и Merge зависит от предпочтений команды разработчиков и особенностей проекта. Оба метода имеют свои плюсы и минусы, и важно выбирать стратегию в соответствии с требованиями проекта, учитывая возможные последствия для истории коммитов и совместной работы.

Я работала в команде, где разработчики постоянно работали в общих веточках и там как раз использовался именно merge. И работала в команде, где разработчики никогда не менялись веточками и мы использовали rebase, чтобы была красивая и понятная история.

Бонус! Как именно rebase изменяет хэш-коды и зачем?

  1. При выполнении rebase указывается ветка, на которую нужно переместить текущую ветку. Например, если у нас есть ветка feature_branch, и мы хотим перебазировать ее на ветку develop, то делаем: git rebase develop
  2. Git находит общего предка (base) между текущей веткой feature_branch и целевой веткой develop. Это коммит, с которого обе ветки начали свою историю.
  3. Git начинает применять каждый коммит из текущей ветки feature_branch поверх целевой ветки develop. Он создает новые коммиты, которые содержат те же изменения, что и оригинальные коммиты, но с новыми хэш-кодами. Почему новыми? Потому что сами коммиты новые и там теперь новые метаданные (например, даты создания, автора и т. д.) и новые родительские коммиты (вместо оригинальных родительских коммитов будут указаны новые коммиты, на которые выполняется rebase).
  4. В процессе применения изменений могут возникнуть конфликты. В таких случаях Git приостанавливает процесс и требует разрешения конфликтов разработчиком. После разрешения конфликтов процесс продолжается. Вот тут главный минус. Например, у нас есть три коммита с одним классом. Гит доходит до первого коммита с проблемным классом и просит решить конфликты. Потом доходит до второго коммита и снова просит решить конфликты. При использовании merge мы бы просто решили конфликты один раз.
  5. По завершении rebase указатель ветки переносится на последний созданный коммит. Теперь ветка feature_branch содержит измененную историю коммитов.
-3

Дубль статей в телеграмме — https://t.me/android_junior

Мои заметки в телеграмме — https://t.me/android_junior_notes

P.S. сделано с помощью ChatGPT и LexicaArt. :)