О слиянии и перебазировании 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
Приведенная выше команда принимает все коммиты, которые существуют в
topic
'но не вmaster
(а именно169a6
а также2c33a
), воспроизводит их наmaster
, а затем перемещает головку ветки к новому наконечнику. Обратите внимание, что старые коммиты [со временем] будут собираться, если на них больше не ссылаются.
Перебазирование использует рабочий каталог и промежуточную область при воспроизведении фиксаций (применить изменения к рабочему каталогу, добавить изменения в промежуточную область, зафиксировать промежуточные изменения, повторить). После того, как все это сделано, в заголовке перебазированной ветви устанавливается последний из новых коммитов (f7e63).
2 дополнительных отличия:
- Слияние и перебазирование служат различным рабочим процессам: см. " Git merge vs. rebase "
- "наши" и "их" различны между слиянием и перебазированием: " Почему значение" наши "и" их "меняется на противоположное "
Нет. C5 и C3'будут иметь разные родительские коммиты, то есть они сами будут разными.
Если вы спрашиваете, будут ли корневые древовидные структуры, на которые ссылаются C5 и C3', идентичны, тогда да (при условии, что любые конфликты были разрешены одинаково). Другими словами, дерево файлов, "содержащихся" в обеих фиксациях, будет одинаковым.
Если вы посмотрите только на содержимое коммитов (то есть не на то, что являются их родителями), то и C5, и C3'содержат одно и то же (при условии, что не было конфликтов слияния или других вещей, требующих изменения вручную). Таким образом, кто-то может подумать, что он такой же, как если бы C3 был удален, для некоторого определения "удалить C3". Но в Git невозможно удалить любые коммиты (все коммиты являются неизменяемыми), поэтому операция удаления коммита из дерева не определена для Git.