Ответ 1
Похоже, первое слияние было быстрым, а второе - трехсторонним слиянием.
Объяснение
Git имеет две версии слияния: ускоренную и трехстороннюю. (Существуют и другие версии, но это не то, что произошло здесь.) По умолчанию поведение заключается в том, чтобы выполнить быстрое слияние, когда это возможно, и в противном случае выполнить трехстороннее слияние.
Быстрое слияние (вы можете принудительно использовать это поведение с опцией --ff-only
, что приведет к сбою слияния при невозможности ускоренной перемотки вперед) может иметь место, когда объединение, которое объединяется, имеет текущую позицию ветвь в ее истории. Например:
A - B - C - D <-master
\
E - F - G <- branch-a
Excecuting git merge
(с настройками по умолчанию) приведет к
A - B - C - D - E - F - G <- branch-a <-master
У вас также не будет возможности редактировать фиксацию слияния, потому что ее нет. Однако, как только это произойдет, ваша другая ветвь расходится с мастером (не просто вперед):
A - B - C - D - E - F - G <-master
\
E1 - E2 <- branch-b
Следовательно, Git не может просто переместить указатель мастера с G
на E2
, потому что это избавит вас от изменений, сделанных в F
и G
. Вместо этого происходит трехстороннее слияние, которое создает фиксацию, которая имеет двух родителей, а также имеет сообщение фиксации. Теперь мастер может быть перенесен на эту фиксацию. (Обратите внимание, что в этой ситуации master и branch-b НЕ указывают на одну и ту же фиксацию.
A - B - C - D - E - F - G - H <-master
\ /
E1 - E2 <- branch-b
Если вы хотите иметь линейную историю, вам нужно использовать rebase, но следует предупредить, что, если кто-либо еще увидит, что ваш филиал совершает это, это может привести к проблемам, выходящим за рамки этого ответа. Использование rebase будет включать в себя два шага, перезагрузку и последующее слияние. Итак, вместо слияния вы сначала выполняете следующее: branch-b, git rebase master
. Это создает новые коммиты, которые являются копиями старых коммитов, т.е. Того же набора изменений, информации об авторе и сообщения, но новой информации об участниках и родительской истории. (Я назову коммиты E1 'и E2' на иллюстрации, чтобы указать, что они являются просто копиями.) Старые коммиты будут существовать до тех пор, пока они не будут собраны в мусор, но не будут доступны, если вы не посмотрите на reflog.)
A - B - C - D - E - F - G <-master
\ \
E1 - E2 \
E1' - E2' <- branch-b
Выполнение git checkout master; git merge --ff-only branch-b
теперь ускорит переадресацию изменений в master, тем самым предоставив вам линейную историю.
A - B - C - D - E - F - G - E1' -E2' <-master <- branch-b