Slider Background

Когда удобно использовать Rebase?

Когда удобно использовать Rebase?

Rebase - это Расширение Mercurial, позволяющее нам менять непропушенную часть дерева изменений в репозитории. Мы можем менять родителей непропушенных коммитов. В идеале мы должны получить вытянутую в одну линию цепочку изменений без ветвления в рамках одной ветки.

Как это работает

Когда мы хотим протолкнуть наш коммит, но обнаруживаем, что кто-то до нас успел протолкнуть что-то ещё, мы не сможем этого сделать, поэтому мы обновляемся и видим следующую картину:



Делая перебазирование нашего коммита, мы меняем родителся с “Пятый коммит” на “Чей-то коммит”, тем самым убирая ветвление:


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

На что следует обратить внимание

При использовании подрепозиториев, нам нужно внимательнее делать Rebase в них. Допустим, репозиторий ссылается на состояние С подрепозитория:

Мы перебазируем С на D и получаем ссылку на несуществующее состояние:

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

Rebase или Merge?

Мы можем действовать стандартным способом и при возникновении подобных ситуаций делать слияние:

Но при большой команде разработки вскоре дерево принимает подобный вид:

В таком дереве двоичным поиском сложней найти сбойную ревизию, да и вообще трудно разобраться в последовательности изменений.
Итак, какой же способ ведения дерева нам выбрать? Если для нас критична история и действительное время коммитов, то мы используем Merge, если же для нас важна простота изучения истории и красота дерева, то выбираем Rebase.
Нужно отметить, что при многопользовательской правки одних и тех же файлов было замечено, что Rebase хуже справляется со слиянием, требуется больше времени, чтобы завершить все изменения.

Насколько Rebase должен упростить нам жизнь?

Какие положительные моменты данного подхода?
  • Дерево выглядит красиво и понятно
  • Удобно следить за историей изменений
  • При необходимости двоичного поиска сбойной ревизии нам надо будет обновиться на меньшее количество ревизий, чем при сильно разветвлённом дереве


Какие отрицательные моменты?
  • Потеря истории слияний, что иногда может привести к невозможности определения источника и виновника ошибки
  • По опыту работы существуют отзывы, говорящие, что трудней проводить громоздкие слияния с Rebase, чем при использовании обычных слияний


Как мы можем обойтись без Rebase?

В принципе, можно сохранить прямое дерево изменений, если перед каждым коммитом обновляться на последнюю ревизию, улаживать конфликты, коммитить и сразу проталкивать изменения. Я сам так всегда делал до того, как узнал про Rebase.
Конечно же, есть положительные и отрицательные стороны подхода:
Положительные:
  • Мы-таки сохраняем дерево стройным и красивым
Отрицательные:
  • При неудачном слиянии можно безвозвратно потерять свои незакоммиченные изменения
  • Не получится разбить задачу на несколько коммитов, сохранив их рядом друг с другом
Хочу отметить, что если задача состоит из нескольких коммитов и имеет довольно большой срок разработки (больше недели), то следует создать отдельную ветку для реализации и потом слить её с рабочей веткой, чтобы обособить масштабные изменения от других правок.