Перевод статьи, посвященной вопросу - что такое fast-forward в системе Git
Оригинал данного вольного перевода размещен здесь - Fast-Forward Git Merge. Статья довольно свежая - от 20.09.2013. Почему перевод статьи? Потому что на русском ничего не нашел (окромя книги официальной).
Слияние (
) ветвей является весьма распространенной и обыденной операцией, выполняемой в системе Git. Однако, в некоторых случаях Git выполняет слияние ветвей в режиме fast-forward. Но что такое режим fast-forward и чем он отличается от обычного режима слияния ветвей.1
merge
Давайте разберем этот вопрос на конкретном примере. Допустим, при работе в репозитории мною была создана ветка
из текущей ветки 1
speedup
:1
master
Поработав некоторое время в этой ветке, я создал несколько
‘ов (три коммита, три белых кружка на рисунке):1
commit
После этого я решил, что работа в ветке
мною выполнена и я сделал 1
speedup
этой ветки на свой удаленный репозиторий.1
push
Между тем, обратите внимание на тот важный факт, что в ветке
не было внесено никаких изменений с того самого момента, когда я сделал ответвление от нее - ветку 1
master
.1
speedup
Когда менеджер проекта уведомится о том факте, что разрабатываемая мною ветка готова для интеграции в проект, то им будет выполнены стандартные шаги по публикации моей работы - команды
и 1
git fetch
. Так как в ветке 1
git merge
не было внесено изменений с того момента (серый кружок), как была создана ветка 1
master
, то при слиянии система Git применит метод fast-forward. В этом случае вся последовательность коммитов будет иметь линейный вид (левая часть рисунка):1
speedup
Примечание переводчика: другими словами, Git просто произведет перемещение указателя HEAD с серого кружка (последний коммит ветки
) на последний белый кружок (последний коммит ветки 1
master
). И будет считать, что все это - ветка 1
speedup
. Получится своеобразный проброс указателя HEAD вдоль последовательной линии коммитов. Именно поэтому автор упоминает термин линейного вида.1
master
Другим вариантом слияния веток в данном случае является использование флага
в команде 1
-no-ff
, что представляет из себя сокращение от - no fast-forward. В этом случае ситуация будет несколько иной - ее схематичное изображение на правой части рисунка вверху.1
git merge
В этом случае при слиянии веток
и 1
master
системой Git создается коммит (кружок со штрихованной границей), задача которого - информировать о слиянии веток. Другими словами - цель и задача этого коммита только в информировании о слиянии веток 1
speedup
и 1
master
.1
speedup
В ситуациях подобного рода система Git всегда старается применить режим fast-forward, если это возможно. Однако, такое поведение Git можно легко изменить на режим no fast-forward и сделать его поведением системы по умолчанию.
Пожалуй, самой главной неприятной неожиданностью при использовании
в режиме no fast-forward - это когда вы нажимаете ту самую зеленую кнопку “Merge” в web-интерфейсе сервиса GitHub при выполнении pull request:1
merge
К сожалению, на сегодняшний день web-интерфейс GitHub выполняет операцию слияния (
) так, как если бы для этой команды был установлен флаг 1
merge
. Другими словами, даже если при слиянии веток ситуация позволяет использовать режим fast-forward, GitHub не будет его использовать.1
-no-ff
Одним из разумных объяснений такого поведения GitHub является тот факт, что каждая операция
должна быть однозначно идентифицирована. К примеру, несколько последних коммитов проекта (в качестве примера мною был взят проект ESLint - ничего личного) могут выглядеть таким образом:1
pull request
Внимательно посмотрите на приведенный выше рисунок. На нем хорошо видно, что некоторые слияния (
) веток могут быть выполнены в режиме fast-forward. Но своеобразный подход GitHub к слиянию веток привел к тому, что линейная история коммитов была превращена в нечто похожее на рисунок железнодорожного пути.1
merge
Если в нескольких словвах подвести общий итог вышесказанного, то он окажется следующим.
Режим no fast-forward хранит всю информацию о слияниях веток. Такой подход может оказаться запутанным и сложным, если необходимо прочитать историю коммитов.
С другой стороны, режим fast-forward хранит не всю информацию о слияниях веток. Такой подход более простой для чтения, но в этом случае становится неочевидным история веток проекта.
На этом все.