Чому 3-бічне злиття вигідніше порівняно з двостороннім злиттям?


165

У Вікіпедії кажуть, що трехстороннє злиття менш схильне до помилок, ніж двостороннє злиття, і часто не потребує втручання користувача. Чому це так?

Приклад, коли 3-х напрямне злиття є успішним, а двостороннє злиття не вдається.

Відповіді:


259

Скажімо, ви та ваш друг перевірили файл та внесли в нього деякі зміни. Ви видалили рядок на початку, а ваш друг додав рядок наприкінці. Потім він вчинив свій файл, і вам потрібно об'єднати його зміни у свою копію.

Якщо ви робили двостороннє злиття (іншими словами, diff), інструмент міг порівняти два файли та побачити, що перший і останній рядки різні. Але як би знати, що робити з відмінностями? Чи повинен об'єднана версія містити перший рядок? Чи повинен він включати останній рядок?

За допомогою тристороннього злиття він може порівнювати два файли, але також може порівнювати кожен із них з оригінальною копією (перш ніж хтось із вас змінив її). Так видно, що ви видалили перший рядок, і що ваш друг додав останній рядок. І вона може використовувати цю інформацію для створення об'єднаної версії.


"Але як би знати, що робити з відмінностями?" Не зрозумів. Якщо він вже може бачити відмінності між двома файлами (без посилання на оригінал), чому він не може послідовно застосовувати обидві зміни в порядку збільшення часових позначок файлів? Тобто: це починається із скоєної копії мого друга, приймаючи його як (новий) оригінал (з додаванням рядка вгорі), а потім, зверху, застосовує мої локальні зміни (видалення рядка на ботоні).
Гаррі

7
@Harry Скажи, що в оригіналі було три лінії (ABC). Він починається з копії мого друга (ABCD) і порівнює його з моєю (BC). Не бачачи оригіналу, можна подумати, що я видалив і A, і D, і кінцевим результатом повинен бути BC.
JW.

80

Цей слайд із презентації перфорсу цікавий:

слайд-зображення

Основна логіка інструменту тристороннього злиття проста:

  • Порівняйте базові, вихідні та цільові файли
  • Визначте "шматки" у файлі вихідного та цільового файлів:
    • Шматки, які не відповідають базі
    • Шматки, які відповідають базі
  • Потім складіть об'єднаний результат, що складається з:
    • Шматки, які відповідають один одному у всіх 3-х файлах
    • Шматки, які не відповідають базі ні в джерелі, ні в цілі, але не в обох
    • Шматки, які не відповідають базі, але відповідають одна одній (тобто вони були змінені однаково як у вихідному, так і в цільовому)
    • Заповнювачі місця, які конфліктують, вирішуються користувачем.

Зауважте, що "шматки" на цій ілюстрації суто символічні. Кожен може представляти рядки у файлі, або вузли в ієрархії, або навіть файли в каталозі. Все залежить від того, на що здатний конкретний інструмент злиття.

Ви можете запитати, яку перевагу пропонує тристороннє злиття над двостороннім злиттям. Насправді, немає такого поняття, як двостороннє злиття, лише інструменти, які відрізняють два файли і дозволяють "злитися", вибираючи шматки з одного чи іншого файлу.
Лише тристороння злиття дає вам змогу знати, чи є шматочок - це зміна походження та чи змінюється конфлікт чи ні.


"зміни конфлікту чи ні." - не показує конфлікт також двостороннє злиття (розл.) (хоча інформація втрачена станом на джерело конфлікту) /
Влад

1
Однак у Git часто зустрічається чотиристорове злиття, де основа насправді не однакова. І все-таки 3-х напрямне злиття є кращим та двостороннім.
Wernight

@Wernight, Чи є 5-ти сторонне злиття?
Pacerier

@Pacerier Не те, про що я знаю, але це те, що відбувається насправді під час вибору вишні або ребазування.
Wernight

Дуже детальне та корисне пояснення
Kaneg

20

Я написав про це дуже докладний пост . В основному ви не можете відстежувати видалення / додавання двостороннім, дуже, дуже непродуктивним.


@pablo, Якщо я додаю функцію перед X, а ви додасте іншу функцію після X, і ми зробимо тристороннє злиття, інструмент автоматично застосує обидві зміни. Але що відбувається, коли моя зміна насправді суперечить вашій зміні (наприклад, кожен з нас створить нову функцію з тим же ім'ям функції)? Як автоматичне злиття повинно знати, що якесь наше "нудно просте" злиття насправді може спричинити конфлікт ?
Pacerier

1
Просто прочитайте ваш підручник, і це мені дуже допомагає. Я почуваюсь так само, як описані вами розробники. Я завжди боявся тристороннього злиття.
racl101

3
Я б запропонував вам скопіювати та вставити частини вашої статті. Я думаю, що це допоможе вам отримати надбавку і буде більше узгоджуватися з філософією стартового потоку.
Самуїл

Гарна стаття. Мені подобалося використовувати патчі для відновлення бази даних, коли ви бачите більше контексту, і ви можете використовувати редактор та оточення для перевірки речей, але є занадто багато ручного пошуку легких речей таким чином. Соромно, що не є приємним способом, який поєднує в собі хороші частини обох
JonnyRaa

20

Тристоронній злиття, коли два набори змін до одного базового файлу об'єднуються під час їх застосування, на відміну від застосування одного, а потім об'єднання результату з іншим.

Наприклад, наявність двох змін, коли додається рядок в одному місці, може бути інтерпретована як два доповнення, а не зміна одного рядка.

Наприклад

Файл a був змінений двома людьми, один додав лося, один додав мишу.

#File a
    dog
    cat

#diff b, a
    dog
+++ mouse
    cat

#diff c, a
    dog
+++ moose
    cat

Тепер, якщо ми об'єднаємо набори змін під час їх застосування, ми отримаємо (3-х напрямне злиття)

#diff b and c, a
    dog
+++ mouse
+++ moose
    cat

Але якщо ми застосуємо b, то подивіться на зміну від b до c це буде виглядати так, що ми просто змінюємо 'u' на 'o' (двостороннє злиття)

    #diff b, c
    dog
--- mouse
+++ moose
    cat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.