Есть ли разница между слиянием --squash и слиянием --no-ff, если ветвь источника (компонента) была удалена вскоре после этого? - PullRequest
1 голос
/ 13 июня 2019

Есть ли разница в отношении окончательного состояния хранилища между слиянием --squash и слиянием --no-ff, если ветвь источника (компонента) удаляется сразу после этого?

Коммит слияния --no-ff будет содержать те же изменения, что и коммит слияния в сквош, верно?

Ответы [ 2 ]

2 голосов
/ 13 июня 2019

Представьте коммиты как узлы на графике (потому что они являются узлами на графике).

Прежде чем делать что-либо еще, у вас есть ситуация, которая выглядит следующим образом:

...--F--G--H   <-- master
            \
             I--J--K   <-- feature

или, возможно, так:

...--F--G--H   <-- master
         \
          I--J--K   <-- feature

Если вы решите запустить git checkout master; git merge --no-ff feature, результатом будет новый коммит на master - мы вызовем этот коммит M для слияния, даже если следующая доступная буква - L - это выглядит так:

...--F--G--H---------M   <-- master
            \       /
             I--J--K   <-- feature

(или аналогичный). первый родитель нового коммита M является существующим коммитом H: тот, который был вершиной master ранее. второй родитель нового коммита M является существующим коммитом K: тот, который был и остается кончиком feature.

(Если ваш начальный граф выглядиткак и во втором примере, где первый коммит, который feature разделяет с master, равен G вместо H, аргумент --no-ff не требуется. Git must делает истинное слияние,так и будет. Если ваш начальный график выглядит как первый пример, --no-ff вынуждает Git выполнить истинное слияние, даже если общий коммит начальной точки уже является вершиной master.)


Если вы запустите git merge --squash вместо git merge --no-ff, вы получите это вместо:

...--F--G--H---------S   <-- master
            \
             I--J--K   <-- feature

, где мы можем вызвать новый коммит S для сквоша вместо M для слияния.Commit S равен точно так же, как M с точки зрения content .Ключевым отличием является то, что коммит S имеет всего один родитель: коммит H.

Ваше последнее действие будет заключаться в удалении name feature.Давайте нарисуем, что для обоих случаев

...--F--G--H---------M   <-- master
            \       /
             I--J--K

и:

...--F--G--H---------S   <-- master
            \
             I--J--K

Now, git log и другие команды Git find фиксируются, начиная с имена ветвей , которые указывают на один конкретный tip коммит, например M или S, и затем работают в обратном направлении.Коммит, который не может быть найден , может также не существовать .Таким образом, примерно через месяц Git очистит и удалит необъяснимые коммиты на втором графике, оставив вам:

...--F--G--H---------S   <-- master

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

0 голосов
/ 13 июня 2019

Да, изменения будут такими же, как и в результате кодовой базы.

Что будет отличаться, это история коммитов.Это может повлиять на некоторые выводы журнала, и маршрут сквоша сделает исходные коммиты недоступными для проверки после удаления ветви объекта.

С другой стороны, маршрут no-ff будет иметь несколько более подробную историю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...