Git стратегия слияния Что такое стратегия «решить»? - PullRequest
0 голосов
/ 04 февраля 2020

Одна из стратегий слияния git слияние - resol :

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

Эта стратегия основана на алгоритме трехстороннего слияния, а также на рекурсивном по умолчанию, но в отличие от рекурсивного , неясно, как он обрабатывает ситуации перекрестного слияния.

Какой алгоритм разрешает обработку перекрестных слияний?

1 Ответ

0 голосов
/ 04 февраля 2020

Во-первых, давайте отметим, что такое «перекрёстное слияние». В Git имя ветви просто идентифицирует last (или tip ) коммит, который является частью этой ветви. Оставшиеся коммиты, являющиеся частью ветви, определяются по следованию родителя этого коммита, родителя его родителя (прародителя), родителя следующего шага назад (прапрадеда) и т. Д .:

... <-F <-G <-H   <--branch

Здесь имя ветви branch идентифицирует коммит, чей настоящий идентификатор ha sh является чем-то большим и уродливым, но мы просто назовем его H. То есть Git считывает содержимое имени branch:

$ git rev-parse branch
<some big ugly hash ID here>

Git использует этот идентификатор ha sh для чтения коммита H из хранилища. Коммит H говорит, что его родительский коммит - это еще один большой уродливый случайный идентификатор га sh, но мы просто назовем его G, поэтому Git может использовать H, чтобы найти га G. sh ID. Git теперь может читать родителя G - H - из хранилища. Коммит G хранит идентификатор F ha sh, так что Git может читать F и т. Д.

Когда у нас есть две ветви с одним лучшим общим предком, это имеет тенденцию выглядеть следующим образом:

          I--J   <-- branch1
         /
...--G--H
         \
          K--L   <-- branch2

Начиная с J и работая в обратном направлении, Git перечисляет коммиты J, затем I, затем H, затем G и скоро. Начиная с L и работая в обратном направлении, Git перечисляет L, затем K, затем H, затем G и т. Д.

Подтверждает H и более ранние на обе ветви. Commit H является последним таким коммитом, поэтому это base merge . Поэтому и -s resolve, и -s recursive выберут коммит H в качестве базы слияния. (После слияния будет сделан новый коммит M, чьи родители будут оба J и L.)

Но не все графики так хороши , В частности, мы можем иметь следующую серию коммитов:

...--G--H---K--L   <-- branch1
         \ /
          x
         / \
...--I--J---M--N   <-- branch2

Чтобы определить, какой коммит использовать в качестве базы слияния, Git начинается с L и идет назад: L, K, H -и-J, G -и-I. То есть Git следует оба родителя слияния совершают K. В то же время, Git начинается с N и работает в обратном направлении: N, M, затем H -and- J и т. Д.

Ясно H -и- J лучше, чем G -и- I, но не существует простого способа разбить t ie между H и J как «лучшего» общего предка. Вот где рекурсивность и разрешение отличаются.

Стратегия рекурсивный выбирает оба фиксируют в качестве базы слияния. Чтобы достичь этого, он вызывает внутренний, внутренний git merge для коммитов H и J. Эта операция слияния находит базу слияния H и J и объединяет их для создания временного коммита, который находится прямо там, где x. Эта новая, но временная фиксация теперь является базой слияния для внешнего слияния.

Стратегия resol - это та, о которой вы спрашиваете в строке темы. Он выбирает один из H или J, по-видимому, случайно. Какой из них вы получите, зависит от используемого алгоритма, который не указан и может меняться от одного Git выпуска к другому.

Какой алгоритм разрешает обработку перекрестных слияний?

Это стратегия -s recursive, которая используется по умолчанию. Как отмечалось выше, он обрабатывает их путем объединения баз слияния.

Вы можете запустить git merge-base --all branch1 branch2 (с примером выше), и вы увидите два идентификатора ha sh двух баз слияния. В некоторых ситуациях (очень трудно нарисовать или, если на то пошло, достичь) может быть три или более баз слияния. (Здесь нет теоретического верхнего предела.) Также каждая пара слияния-базы может иметь несколько баз слияния. Рекурсивная стратегия обрабатывает все эти случаи путем многократного слияния баз слияний, пока в итоге не останется один лучший (но временный) коммит.

Когда рекурсивное слияние выполняет рекурсивное слияние, конфликты, возникающие во время внутренних слияний, незаметно передаются - вместе с маркерами конфликтов - в конечную базу слияния, используемую для слияния. Результат очень сбивает с толку .

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