О Git слияния и переустановки

enter image description here

enter image description here

enter image description here

Вышеприведенный результат является результатом слияния и rebase.

Мой вопрос в том, что в конечном состоянии C5 и C3 ' идентичны?

Или скажите, git rebase равно git merge + удалить C3?

Ответ 1

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

Кроме того, до тех пор, пока конфликт не будет разрешен, или если вы разрешаете конфликты одинаково каждый раз, конечный контент C3 'и C5 будет таким же, но они остаются различными коммитами (поскольку C3' и C5 имеют разных родителей, у них также будут разные хэши, что более очевидно на иллюстрациях ниже). Соответственно, записанная история для каждого отличается. Примечание для rebase, история является линейной, а для слияния это lattice.

Рассмотрим тот же вопрос, когда слияние/перезагрузка совершает несколько коммитов, как показано на рисунке A Visual Git Reference "от Марка Лодато. Вы увидите, что конечный результат совсем другой.

git checkout master
git merge other # update master with tip of branch 'other' changes

git merge other

Вы принимаете только:

  • текущий фиксатор (ed489 ниже, поскольку вы находитесь на главном сервере),
  • последняя фиксация другой ветки (которая представляет собой моментальный снимок, представляющий полное содержимое репо при разветвлении в other, а не дельта)
  • их общий предок (b325c) и выполняет трехстороннее слияние.

В значении рабочего каталога и этапа на этой диаграмме обратите внимание на стрелки, идущие на трехстороннее слияние, а затем на рабочий каталог и этап. Рабочий каталог представляет все файлы, которые вы видите (на вашем жестком диске), некоторые из которых изменены в результате трехстороннего слияния. На сцене хранятся файлы, измененные с помощью трехстороннего слияния, которые затем используются для создания нового фиксации (f8bc5).

Это сильно отличается от rebase, который стремится к повторно применять каждое фиксацию ветки поверх ветки назначения:

git checkout topic # this time we are on topic
git rebase master  # means: recreate every topic commits on top of master
                           at the end, we are still on (new) 'topic' branch

git rebase master

Вышеприведенная команда принимает все коммиты, которые существуют в 'topic', но не в master (а именно 169a6 и 2c33a), повторяет их на master и затем перемещает ветвь ветки на новый наконечник. Обратите внимание, что старые коммиты будут [в конечном итоге] собирать мусор, если они больше не ссылаются.

Rebasing использует рабочий каталог и промежуточную область при повторном коммите (применяет изменения в рабочем каталоге, добавляет изменения в промежуточную область, фиксирует поэтапные изменения, повторяет). Как только все это будет сделано, голова переустановленной ветки будет установлена ​​на последний из новых коммитов (f7e63).


2 дополнительных отличия:

Ответ 2

Нет. C5 и C3 'будут иметь разные родительские коммиты, то есть они сами будут разными.

Если вы спрашиваете, будет ли корневой дерев, на который ссылаются C5 и C3 ', будут идентичны, тогда да (при условии, что любые конфликты были разрешены одинаково). Другими словами, дерево файлов, содержащихся в "обоих коммитах", будет одинаковым.

Ответ 3

Если вы посмотрите только на содержание коммитов (т.е. не на то, что есть у их родителей), то оба C5 и C3 содержат одно и то же (если не было конфликтов слияния или других вещей, требующих ручного изменения). Поэтому кто-то мог подумать об этом как о том, что если C3 был удален, для некоторого определения "удалить C3". Но в Git невозможно удалить какие-либо коммиты (все коммиты неизменяемы), поэтому операция удаления фиксации из дерева не определена для Git.