Реализация трехстороннего сравнения / слияния
Я пытаюсь реализовать трехсторонний алгоритм сравнения / слияния (в python) между, скажем, базовой версией X и двумя разными производными версиями A и B, и мне трудно понять, как обрабатывать некоторые изменения.
У меня есть построчное сравнение от X до A и от X до B. Эти различия дают для каждой строки "код операции", который либо =
если линия не изменилась, +
если строка была добавлена, -
если линия была удалена, и c
если строка была изменена (что просто -
сразу же после +
, указывая на то, что строка была удалена, а затем заменена, эффективно модифицирована).
Сейчас я сравниваю соответствующие коды операций из A-diff и B-diff, чтобы попытаться решить, как их объединить. Некоторые из этих комбинаций кода операции просты: =
а также =
означает, что ни одна из версий не изменила строку, поэтому мы сохраняем оригинал. +
а также =
означает, что на одной стороне была добавлена строка, а на другой не было внесено никаких изменений, поэтому примите добавление и переходите к следующей строке только на той стороне, которая добавила эту строку. А также -
а также c
конфликт, который пользователь должен разрешить, потому что одна сторона строки была изменена, а другая сторона была удалена.
Тем не менее, я борюсь с тем, что делать с +
и -
или +
и c
, Например, в первом случае я добавил новую строку на одной стороне и удалил следующую строку на другой стороне. Строго говоря, я не думаю, что это конфликт, но что, если дополнение полагалось на то, что эта строка была там? Я предполагаю, что это относится ко всей вещи (что-то добавленное в одном месте может полагаться на что-то другое, чтобы иметь смысл). Второй случай аналогичен, я добавил строку с одной стороны, а с другой стороны я изменил следующую строку, но добавление может основываться на исходной версии строки.
Каков нормальный подход к решению этого?
0 ответов
Обычная надежная стратегия (diff3, git's resolve ...) заключается в том, что изменения (+ - c) в одном файле должны находиться на расстоянии минимум N (например, 3) контекстных строк от конкурирующих изменений в другом файле - если они не являются точно равными. В противном случае это конфликт для ручного разрешения. Подобно требованию некоторого чистого контекста в приложении исправления.
Вот пример, когда sb пробует некоторые причудливые дополнительные стратегии, такие как "# если два действия Delete перекрываются, взять объединение их диапазонов", чтобы уменьшить определенные конфликты. Но это рискованно; и, скорее, с другой стороны, нет гарантии, что одновременные изменения не приведут к проблемам, даже если они находятся очень далеко.