О слиянии и перебазировании Git

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

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

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

3 ответа

Решение

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

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

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

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

мерзавец слияния других

Вы берете только:

  • текущий коммит (ed489 ниже, так как вы на мастере),
  • последний коммит из ветки other (это моментальный снимок, представляющий весь контент репо, когда он разветвляется в ' 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

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

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


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

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

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

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

Другие вопросы по тегам