Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як працює трибічне злиття в Git і що таке merge-base і стратегія ort?

Трибічне злиття (three-way merge) порівнює не дві версії, а три:

  • base - спільний предок обох гілок (merge-base);
  • ours - поточна гілка;
  • theirs - гілка, яку зливають.
git merge-base main feature    # хеш спільного предка

Правило для кожного фрагмента:

base ours theirs результат
X X Y Y (змінили лише вони)
X Y X Y (змінили лише ми)
X Y Y Y (змінили однаково)
X Y Z конфлікт

Саме спільний предок дозволяє зрозуміти, хто змінив рядок. Порівнюючи лише дві версії, неможливо відрізнити «ми додали рядок» від «вони його видалили».

Конфлікт із базою легше розв'язувати, якщо бачити всі три версії:

git config --global merge.conflictStyle zdiff3
<<<<<<< HEAD
$total = round($sum * 1.2, 2);
||||||| base
$total = $sum * 1.2;
=======
$total = $sum * $vatRate;
>>>>>>> feature

Видно: одна сторона додала округлення, інша - змінну ставки. Правильний результат поєднує обидві зміни.

Кілька спільних предків (criss-cross merge - гілки зливалися одна в одну кілька разів): рекурсивна стратегія спершу зливає предків між собою у «віртуальну базу», а потім використовує її.

Стратегія ort («Ostensibly Recursive's Twin») - за замовчуванням з Git 2.34 замість recursive:

  • той самий результат для звичайних випадків, але значно швидше на великих репозиторіях і з великою кількістю перейменувань;
  • краще розпізнає перейменування й не торкається робочого каталогу, поки результат не обчислено;
  • лежить в основі git merge-tree --write-tree - злиття без робочого каталогу (так сервіси на кшталт GitHub перевіряють, чи можна злити pull request).

Інші стратегії й параметри:

  • -X ours / -X theirs - у конфліктних фрагментах автоматично взяти свою чи їхню версію (неконфліктні зміни обох сторін зберігаються);
  • -s ours - ігнорувати зміни іншої гілки повністю, лише записати факт злиття (не плутати з -X ours);
  • octopus - злиття більше ніж двох гілок за раз, без ручних конфліктів.

Що не розв'язує жодна стратегія: семантичні конфлікти. Одна гілка перейменувала метод, інша додала новий виклик старого імені - текстово конфлікту немає, а код зламаний. Тому після злиття запускають тести.

Докладніше в документації: Git: стратегії злиття

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання