3-Way Merge в git — как работает сравнение

У меня есть три версии файла:

version 1       common ancestor      version  2
-------------   ---------------      ------------- 
before          original line        original line
original line                        after

Что происходит при сравнении этих версий для создания окончательной версии слияния?

Я прочитал некоторую информацию по этой теме, но я все еще не понимаю, как именно это работает.

Что касается последнего примера:

Является ли сравнение отдельных строк между версиями линейным? Если это так, то окончательное слияние должно выглядеть так:

1 line: before
2 line: conflict (both left and right contributors are changed compared to ancestor) 

Это правильное понимание или это работает по-другому?


person Dusan Cani    schedule 23.06.2017    source источник
comment
Вы можете просто попробовать это. Создайте репозиторий и сделайте первоначальный коммит с файлом, который содержит кучу строк. Сделайте ветку (или две, если хотите). Извлеките ветку и измените файл, добавив строку выше, затем добавьте и зафиксируйте. Проверьте другую ветку (или мастер) и измените файл, добавив строку ниже, затем добавьте и зафиксируйте. Затем попросите Git выполнить слияние и посмотрите на результат. См. также stackoverflow.com/q/44359334/1256452.   -  person torek    schedule 23.06.2017


Ответы (2)


Трехстороннее слияние обычно означает, что вместо простого сравнения конечного результата для выполнения слияния уже рассматривается общая базовая версия. Затем Git создает представление изменений для каждой версии.

Итак, что он на самом деле получает по сравнению с базовой версией, так это следующее:

version 1           version  2
-------------       -------------
+before              original line
 original line      +after

Затем он будет использовать общие строки в качестве контекста для выравнивания изменений:

version 1           version  2
-------------       -------------
+before
 original line       original line
                    +after

В этот момент слияние легко разрешить без конфликта со следующим:

before
original line
after

Обратите внимание, что такое слияние все равно может привести к конфликту, потому что у Git может не хватить общего контента для правильного выравнивания изменений. Особенно для очень маленьких файлов это может случиться.

person poke    schedule 23.06.2017

Я не думаю, что слияние выполняется путем «сравнения» отдельных строк напрямую между версией 1 и версией 2. Это более сложно. Речь идет о попытке увидеть, где различия между common-ancestor..version1 и common-ancestror..version2 могут быть "объединены". В вашем конкретном случае в исходной версии есть одна строка, верно? Я думаю, что если бы строка имела EOL в конце перед EOF, то их слияние не сломается (потому что эта строка будет присутствовать в обеих окончательных версиях), и поэтому она будет слита совершенно нормально. . Однако, если бы строка не имела EOL в конце, то версия 2 удалила бы эту строку (поскольку исходной строки больше нет... теперь это другая строка из-за EOL), и тогда у вас возникнет конфликт.

person eftshift0    schedule 23.06.2017
comment
Я только что проверил оба способа, и это сработало так, как я описал. - person eftshift0; 23.06.2017