Почему изменение смежных строк, но изменение независимо вызывает конфликт git merge? - PullRequest
3 голосов
/ 21 марта 2019

Скажем, я начинаю с одного коммита на мастере в test.txt, просто строка Hello world!, за которой следует новая строка (чтобы не допустить различий в первой строке при добавлении второй строки).

Затем я разветвляю этот коммит с именем ветки modification.Здесь я изменяю файл с

Hello world!

на

Hello world!
This is another line.

и затем фиксирую эту ветку.

Затем я проверяю master и изменяю файл с

Hello world!

на

Hello world! This is a new thing.

И затем я фиксирую это на master.Таким образом, в обоих коммитах я просто меняю одну строку.Поскольку у меня в начале был перевод строки на master, дополнительный коммит на master only изменяет строку 1, в то время как commit на modification only изменяет строку 2. Следовательно, яне понимаю, почему это приводит к конфликту слияния, когда я пытаюсь слить modification в master.Однако, я получаю это как diff3 вывод.

<<<<<<< HEAD
Hello world! This is a new thing.
||||||| merged common ancestors
Hello world!
=======
Hello world!
This is another line.
>>>>>>> modification

Почему бы git не понять, что они меняют отдельные строки и объединяют эти две вместе?Я бы подумал, что потребуется модификация строки 1 из коммита на master и модификация строки 2 на modification, чтобы сформировать:

Hello world! This is a new thing.
This is another line.

Единственная возможность, о которой я могу думать, - это что-то о модификацииодин и тот же кусок независимо от номера строки.

Интересно, что если вместо modifications я добавлю This is another line. в строку 3 вместо строки 2, оставив эту пустую строку в ветви modification, объединение будет продолжено без конфликтов.

1 Ответ

2 голосов
/ 21 марта 2019

У вас правильная идея: Git объявляет конфликт, если две "стороны" касаются "одинаковых строк" "одного и того же файла" по сравнению с содержимым этого файла в коммите базы слияния. Хитрость заключается в определении того же файла и той же строки . Коммит слияния - это ваш первый коммит, в котором было test.txt с одной строкой, читающей Hello world!. Две подсказки ветви имеют test.txt с другим содержимым.

С философской точки зрения, определение того же файла - сложная проблема: см. парадокс Корабля Тесея . Git, однако, просто объявляет, что если файл test.txt существует во всех трех коммитах - в базе слияния и в обоих коммитах tip tip - тогда это "тот же файл". Так что это решает эту проблему прямо сейчас. ? Тем не менее, «та же линия» все еще немного размыта.

Изменение, которое вы внесли из первого когда-либо сделанного коммита в первый коммит с ветвлением, оставило только одну строку слева, но изменило конец файла, добавив This is another line.

Изменение, которое вы внесли из первого когда-либо сделанного коммита во второй совет ветвления - новый master совет перед слиянием - изменило саму строку 1.

Git становится немного белоснежным на краях измененной области - в действительности, иногда происходят между строками. Эти изменения касаются как выше, так и ниже линий. В конечном счете, это всего лишь причуда алгоритма, выбранного для решения вопроса о конфликте изменений: Git решает сказать, что эти изменения затрагивают одну и ту же строку (и), в то время как другой алгоритм может сказать, что это не так.

(Краевые эффекты возникают из-за необходимости иметь непустые интервалы, чтобы избежать проблем с ограждением. Различные алгоритмы в основном используют полуоткрытые интервалы: область начинается с символа X - здесь строки действуют как символы - и заканчивается перед символом Y. Концу файла обычно назначается символ EOF для этой цели. Некоторым алгоритмам нравится иметь символ «выше» первой строки, как своего рода SOF или начало файла.)

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