Не очень удобный способ сделать это, но вы можете создать его из инструментов, предоставляемых Git. Основной требуемый инструмент - это git merge-file
, который выполняет трехстороннее объединение для одной тройки версий файлов, то есть base + our + их. Он принимает параметры --ours
и --theirs
для разрешения конфликтов так же, как -X ours
и -X theirs
для общего слияния, т. Е. Он не просто берет наш файл или их file , он берет наши или их только в конфликтных точках.
Это все замечательно, но где взять три версии? Git остановился из-за конфликта слияния, скажем, main.py
. В вашем рабочем дереве main.py
содержит беспорядок, оставленный Git, с маркерами <<<<<<< ... >>>>>>>
вокруг конфликтующих строк. Но для git merge-file
нужны три неотмеченных входных файла: базовая версия слияния, «наша» версия и «их» версия. Но эти три файла находятся в индексе! Если файл F имел конфликт, существует :1:<em>F</em>
с базовой версией слияния, :2:<em>F</em>
с нашей и :3:<em>F</em>
с их.
Чтобы получить их, вы можете использовать git show
или git checkout-index
. Последний действительно правильный инструмент: git mergetool
использует git checkout-index
, с этой маленькой функцией оболочки:
checkout_staged_file () {
tmpfile=$(expr \
"$(git checkout-index --temp --stage="$1" "$2" 2>/dev/null)" \
: '\([^ ]*\) ')
if test $? -eq 0 && test -n "$tmpfile"
then
mv -- "$(git rev-parse --show-cdup)$tmpfile" "$3"
else
>"$3"
fi
}
Вызывается как checkout_staged_file 1 main.py main.py.base
, например, он извлекает копию этапа 1 (базы слияния) от main.py
до main.py.base
. Повторите с 2 и 3 и подходящими вариантами для третьего аргумента, чтобы получить все три файла. Затем запустите git merge-file
для трех файлов, как описано в документации git merge-file
.
(Подробнее см. исходный код git mergetool
. Это просто большой сценарий оболочки, поэтому его довольно легко читать и изменять для собственных целей.)