null

Git merge против git rebase: выбери свой путь в мире версионирования

Вступление

В мире программирования эффективное управление версиями кода играет ключевую роль в обеспечении качества и стабильности программного обеспечения. Система контроля версия Git предоставляет разработчикам мощные инструменты для работы с ветками и историей изменений. Два из таких инструментов — git merge и git rebase — часто используются для интеграции изменений в разных ветках, но они имеют свои уникальные особенности и преимущества.

Многие новички в Git склонны избегать git rebase, опасаясь его сложностей и возможных последствий для истории версий. Это страх нередко обусловлен недостатком опыта и понимания, как правильно использовать этот инструмент. Тем не менее, git rebase может предложить более чистый и логически структурированный журнал изменений, что делает его полезным в некоторых ситуациях. В этой статье мы рассмотрим различия между git merge и git rebase.

Данная статья будет опираться на книгу Git Pro (Scott Chacon).

1. Git merge

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

1.1 Пример

Рассмотрим следующую историю разработки: 

             A---B---C topic <-
            /
    D---E---F---G master

Мы имеем две ветви: topic и master. В текущий момент мы находимся в topic. Наша задача: слить изменения из неё в master. Выполним следующую команду:

git checkout master

             A---B---C topic
            /
    D---E---F---G master <-

Теперь мы находимся в master. Далее выполним следующую команду.

git merge topic

Рассмотрим историю разработки, после успешного выполнения команды:

             A---B---C  topic
            /                \
    D---E---F---G---H  master <-
Важно отметить, что в процесс слияния остановится, если возникает конфликт, который не может быть разрешен автоматически!

Примерная последовательность коммитов в выводе команды git log:

D--E--A--F--B--G--C--H

1.2 Плюсы и минусы

Из плюсов команды можно выделить:

  1. Простота использования
  2. Сохранение полной истории разработки, а так же соблюдение хронологического порядка
  3. Создание нового коммита, сообщающего о выполнении команды

Из минусов можно выделить:

  1. История коммитов может заполняться "ненужными" коммитами
  2. Довольно сложная отладка процесса слияния

1.3 Литература

Подробнее про git merge и параметры данной команды можно почитать здесь.

2. Git rebase

Преобразование - это процесс перемещающий одну последовательность коммитов к новому базовому коммиту. В процессе данной операции Git создает новые коммиты и применяет их к указанному основанию. Это важно понимать. ведь в действительности новая часть ветки всегда будет состоять из совершенно новых коммитов.

2.1 Пример первый

Предположим, что существует следующая история с текущей веткой topic

          A---B---C topic <-
         /
    D---E---F---G master

Выполним одну из следующих команд

git rebase master
git rebase master topic
                  A'--B'--C' topic <-
                 /
    D---E---F---G master

2.2 Пример второй

Если topic имел бы изменение, которое уже было внесено (допустим, был отправлен некоторый патч, который был применен в master ветки), то данный коммит с изменением будет пропущен и будет выдано предупреждение. 

          A---B---C topic <-
         /
    D---E---A'---F master

В результате будет получен следующий результат:

                   B'---C' topic <-
                  /
    D---E---A'---F master

2.3 Плюсы и минусы

Из плюсов данной команды можно выделить:

  1. История проекта становится более читаемой и понятной. Изменения линейны.
  2. Изменения применяются поочередно, что приводит к более чистому состоянию истории, ведь потенциальные конфликты тоже устраняются постепенно.
  3. Есть возможность объединять или очищать коммиты.

Из минусов можно выделить:

  1. Данная команда изменяет историю коммитов и их хэш-коды.
  2. Встречаются конфликты более болезненные чем при merge.
  3. Сжатие коммитов может скрывать полезную информацию

2.4 Литература

Подробнее про git rebase можно прочитать здесь.

3. Git rebase -i (Интерактивное перемещение)

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

3.1 Пример

Рассмотрим уже известную нам историю:

          A---B---C topic <-
         /
    D---E---F---G master

Выполним следующую команду

git rebase -i master

Откроется редактор, в котором будут перечислены все коммиты, планируемые к перемещению.

pick 11d2d3c A
pick 22e3a4b B
pick 33f4d5h C

Данный список предоставляет информацию о том, как будет выглядеть ветка после перемещения. Есть возможность изменить её, сделав историю такой, какой вы захотите. Есть возможность использовать следующие команды:

Commands:
p, pick = use commit
r. reword = use commit, but edit the commit message
e, edit = use commit, but stop for amending
s, squash = use commit, but meld into previous commit
f, fixup = like "squash", but discard this commit's log message
x, exec = run command (the rest of the line) using shell
d, drop = remove commit

В редакторе, который был открыт выше, изменим некоторую информацию:

pick 11d2d3c M
fixup 22e3a4b B
f 33f4d5h C

В результате выполнения данной команды история будет выглядеть так

                      M topic <-
                     /
D---E---F---G master

Подводя итоги, можно сказать,что rebase не изменяет целевую ветку, он лишь переносит изменения из текущей ветки на вершину целевой, причем указатель остается на вершине текущей.

Резюме 

Выбор между rebase и merge зачастую будет зависеть от "исторически сложившихся" обстоятельств и привычек в вашей команде. Оба метода имеют свои плюсы, минусы и особенности в работе. При работе в общих ветках рекомендуется использовать merge. При работе в команде, где разработчики не меняются часто ветками и следят за чистой, красивой и понятной историей предпочитается использовать rebase

Назад