WinMerge реализует то, что люди иногда называют «двусторонним слиянием». Это неправильно, так как двустороннее «слияние» - это вовсе не слияние: это просто diff, за которым следует управляемое применение этого diff. См. Почему трехстороннее слияние выгоднее двухстороннего слияния?
В WinMerge также реализовано трехстороннее слияние. Git only реализует трехстороннее объединение в своих алгоритмах объединения (git merge
и git merge-file
). То есть должен быть общим базовым файлом.
Поэтому вам придется использовать что-то отличное от Git, чтобы выполнить слияние на уровне файлов, или придумать общую базу file:
- Вам не нужен общий предок commit (как в ответе bk2204 ), но иметь его намного проще, потому что Git сам тогда сделает всю работу. Общий базовый файл происходит из общего базового коммита слияния.
- Вам нужно нужен общий базовый файл , однако, если вы хотите использовать Git tools.
Другими словами, если хотите, вы можете:
- Начать объединение, используя
git merge --allow-unrelated-histories
. - Let Git stop с сообщениями о
CONFLICT (add/add)
. - Для каждого результата слияния, находящегося в этом конфликтующем состоянии:
- Выберите два или три файла. Два найденных Git легко получить. Поиск или создание общей базы слияния - ваша собственная проблема; Git не имеет ответа для вас здесь.
- Используйте любой инструмент по вашему выбору для получения результата слияния. Это может быть
git merge-file
, WinMerge или что угодно. - Скажите Git: этот результат слияния является правильным результатом слияния . Git примет все, что вы дадите, в качестве правильного результата слияния.
- Теперь, когда вы разрешили все конфликты, завершите sh слияние.
Относительно легко, например, с использованием сценариев bash, автоматизировать часть "для каждого конфликтующего файла". git status
сообщает вам, какие файлы находятся в UU
(не объединенном) состоянии, так что вы получаете набор файлов имен . Затем вы можете использовать git ls-files --stage <name>
для каждого имени файла, чтобы убедиться, что для этого имени действительно есть индексная запись в слот-2 и слот-3, и нет записи в слот-1, т. Е. Что это конфликт «добавить / добавить». , Затем вы можете использовать довольно неудобный для пользователя вариант git checkout-index
, чтобы получить два конфликтующих входных файла во временные файлы.
Фактически, git mergetool
выполняет все вышеперечисленное для вас, а затем запускает любой произвольный Команда на ваш выбор. Если есть возможность запустить WinMerge для этих файлов непосредственно из git mergetool
, это может быть способом справиться с этим.
Другими словами, git mergetool
делает "для каждого конфликтующего слияния, получите три файла с Git "часть работы. Поскольку Git не нашел общий файл базы слияния, git mergetool
предоставляет пустой файл в качестве базы слияния для выбранного вами инструмента. Вы можете, зная (или проверяя), что этот файл пуст, просто выбросить файл и выполнить «двустороннее слияние» - действительно управляемое приложение diff - для получения правильного результата.
(у меня есть не знаю, как запустить сам WinMerge, будь то инструмент слияния, вызванный из git mergetool
или любым другим способом. Так что эту часть вам нужно будет найти или выяснить самостоятельно.)