Как установить kdiff3 в качестве инструмента слияния для SVN

Я хотел бы иметь возможность разрешать конфликты с помощью kdiff3, когда SVN уведомляет меня о конфликте. Как я могу установить его в качестве инструмента по умолчанию для этого?

4 ответа

Решение

Перейдите в файл конфигурации Subversion (/etc/subversion/config или же ~/.subversion/config) и установить merge-tool-cmd переменная с вашим любимым инструментом:

### Set merge-tool-cmd to the command used to invoke your external
### merging tool of choice. Subversion will pass 4 arguments to
### the specified command: base theirs mine merged
# merge-tool-cmd = merge_command

Хотя есть проблема с kdiff3, который не поддерживает четыре простых аргумента (SVN передает четыре простых аргумента в kdiff3, и он не работает), поэтому он обычно вызывается с помощью простого скрипта для перевода аргументов, например, "kdiff3caller":

#!/bin/sh
kdiff3 "$1" "$2" "$3" -o "$4"

Эта проблема и решение kdiff3 объяснены здесь.

Решение, которое короче и работает с более поздними версиями SVN (протестировано на SVN 1.7.7):

Создать скрипт ~/svn-merge-kdiff

#!/bin/bash

# Useful when something fails
LOG=~/svn-merge-kdiff-last-run.log
echo "arguments passed to $0: $@" > $LOG

# Now, don't think you will get the $1, $2, etc... by referencing.
# At first, you have to copy it to an array
for i in $@; do
    args=( ${args[@]} $i )
done

echo "parsed args" >> $LOG
for i in ${args[@]}; do
    echo $i >> $LOG
done

# I keep it in case something changes
if [ "${args[1]}" == "-m" ] && [ "${args[2]}" == "-L" ] && [ "${args[3]}" == ".mine" ];then
    command="kdiff3 --L1 ${args[5]} --base ${args[9]} --L2 ${args[7]} ${args[10]} --L3 ${args[3]} ${args[8]} -o merged"
    $command
    if [[ $? -ne 0 ]]; then
        echo "$command failed" >> $LOG
        exit 1
    fi

    # You have to do this, otherwise after the merge you will see... empty file(?)
    cat merged

    rm merged
    exit 0
fi

exit -1

Свяжите это с SVN в ~/.subversion/config

diff3-cmd = ~/svn-merge-kdiff

Я нашел этот сценарий там, где не помню. но автор Майкл Брэдли.

Мой ответ похож на ответы Джона Андера Ортиса Дурантеса. Так что, если его ответ не работает, у вас есть резервная копия. Однажды я попробовал что-то вроде того, что он предложил, но он всегда выводил какую-то ошибку с параметрами, пока не нашел этот сценарий, который разрешил все.

Создайте файл сценария и установите diff-cmd = /path/to/script.sh в вашем ~/.subversion/config

#!/bin/bash

# Возвращает код ошибки 0 при успешном объединении, 1, если в результате остаются неразрешенные конфликты #. Любой другой код ошибки будет считаться фатальным.
# Автор: Майкл Брэдли # ПРИМЕЧАНИЕ: весь вывод должен быть перенаправлен в stderr с помощью "1> & 2", так как весь вывод stdout записывается в выходной файл # Должен вызываться с помощью subversion в файле "~/.subversion/config" # Добавить конфигурацию: "diff-cmd = /path/to/script/myKdiff3.sh" 

VDIFF3="kdiff3"
DIFF3="diff3" 
DIFF="kdiff3"  

promptUser ()
{читать вариант ответа "${answer}" в "M") 
        echo "" 1>&2
        echo "Попытка слияния ${baseFileName} с ${DIFF}" 1>&2
        $VDIFF3 $ более старых $ mine $ своих --L1 $labelOlder --L2 $labelMine --L3 $labelTheirs -o $output 1>&2
        bLoop=1
        if [ -f $output ]; тогда если [ -s $output ]; затем #output успешно записано bLoop=0
            fi
        fi
        if [ $bLoop = 0 ]; затем cat $output
            rm -f $output
            exit 0
        else
            echo "Слияние не выполнено, повторите попытку" 1>&2
        fi;;

        "m") 
        echo "" 1>&2
        echo "Попытка автоматического слияния ${baseFileName}" 1>&2
        diff3 -L $labelMine -L $labelOlder -L $labelTheirs -Em $mine $old $ их s> $, если выводится [ $? = 1 ]; then
            # Невозможно автоматически объединить rm -f $output
            $VDIFF3 $ старше $ mine $ своих --L1 $labelOlder --L2 $labelMine --L3 $labelTheirs -o $output --auto 1>&2
            bLoop=1
            if [ -f $output ]; тогда если [ -s $output ]; затем #output успешно записано bLoop=0
            fi
        fi
        if [ $bLoop = 0 ]; затем cat $output
            rm -f $output
            exit 0
        else
            echo "Слияние не удалось, попробуйте еще раз" 1>&2
            fi
        else
            # Мы можем выполнить автоматическое объединение, и мы уже это сделали cat $output
            rm -f $output
            exit 0
        fi;;

        "diff3" | "Diff3" | "DIFF3")
        echo "" 1>&2
        echo "Diffing..." 1>&2
        $VDIFF3 $ старше $ mine $ их --L1 $labelOlder --L2 $labelMine --L3 $labelTheirs 1>&2;;

        "diff" | "Дифф" | "DIFF")
        echo "" 1>&2
        echo "Diffing..." 1>&2
        $DIFF $mine $ itss -L $labelMine -L $labelTheirs 1>&2;;

        "А" | "a") 
        echo "" 1>&2
        echo "Принятие удаленной версии файла..." 1>&2
        cat ${itss}
        exit 0;;

        "Я" | "i") 
        echo "" 1>&2
        echo "Сохранение локальных изменений..." 1>&2
        cat ${mine}
        exit 0;;

        "R" | "r") 
        echo "" 1>&2
        echo "Возвращение к основанию..." 1>&2
        cat ${старше}
        exit 0;;

        "D" | "d") 
        echo "" 1>&2
        echo "Runnig diff3..." 1>&2
        diff3 -L $labelMine -L $labelOlder -L $labelTheirs -Em $mine $old $ их s
# Выход с возвращаемой версией diff3 (чтобы записать файлы при необходимости) выйти из $?;;

        "S" | "s") 
        echo "" 1>&2
        echo "Сохранение на потом..." 1>&2
        cat ${mine}
        # Выход с возвращаемым значением 1 для принудительной записи файлов exit 1;;

        "Fail" | "провал" | "FAIL") 
        echo "" 1>&2
        echo "Failing..." 1>&2 
        exit 2;;

        "H" | "h") 
        echo "" 1>&2
        echo "ВАРИАНТЫ ИСПОЛЬЗОВАНИЯ:" 1>&2 
        echo "  [A]ccept    Accept $labelTheirs и выбрасывать локальные модификации" 1>&2
        echo "  [D]efault Использовать diff3 для объединения файлов (то же поведение как ванильный SVN)" 1>&2
        echo "  [Fail] Удаляет команду (не рекомендуется)" 1>&2
        echo "  [H]elp Распечатать это сообщение " 1>&2
        echo "  [I]gnore Сохранить локально измененную версию как is" 1>&2
        echo "  [M]erge Объединить вручную, используя ${VDIFF3}" 1>&2
        echo "  [m]erge То же, что и "M", но при необходимости попытаться автоматически объединить " 1>&2
        echo "  [R]evert    Revert в базовую версию (${labelOlder})" 1>&2
        echo "  [S]ave То же, что и 'I', но записывает файлы rold, rnew и rmine для работы с более поздними " 1>&2
        echo "  [diff] Тип 'diff'для сравнения версий $ labelMine и $labelTheirsthe перед принятием решения " 1>&2
        echo "  [diff3] Введите "diff3" для сравнения всех трех версий перед принятием решения " 1>&2
        echo "" 1>&2;;

        *) 
        echo "${answer}" не вариант, попробуйте еще раз." 1>&2;;
    esac 
}

if [ -z $2 ] затем echo ОШИБКА: ожидается, что этот скрипт будет вызван выходом subversion 1 fi, если [ $2 = "-m" ], тогда #Setup vars
    labelMine=${4}
    labelOlder=${6}
    labelTheirs=${8}
    mine=${9} старше =${10} их =${11}
    output=${9}.svnDiff3TempOutput
    baseFileName=`echo $mine | sed -e "s/.tmp$//"`

    #Prompt пользователь для направления, в то время как [ 1 ] ​​делает echo "" 1>&2
        echo "${baseFileName} требует слияния." 1>&2 
        echo "" 1>&2
        echo "Что бы вы хотели сделать?" 1>&2
        echo "[M]erge [A]ccept [I]gnore [R]evert [D]efault [H]elp" 1>&2 
        promptUser
    done
else
    L="-L"         # Параметр аргумента для левой метки R="-L"         # Параметр аргумента для правой метки label1=$3       # Левая метка label2=$5       # Правильный файл file1=$6        # Левый файл file2=$7        #Правильный файл $DIFF $file1 $file2 $L "$label1" $L "$label2" &
    #$DIFF $file1 $file2 &
    #wait, чтобы команда закончила ждать fi
exit 0

Сценарий из ответа yvoyer отлично работает для меня, и я использую SVN 1.4. Я думаю, что предыдущий ответ от Jon Ander Ortiz Durántez работает для SVN 1.5 и выше, и этот скрипт работает для версий SVN до 1.5. Похоже, что были изменения в --diff-cmd & --diff3-cmd для версии 1.5. Сравните сценарии в следующих двух документах SVN, чтобы увидеть некоторые различия:

Сценарий Майкла Брэдли действительно полезен, так как теперь, если я получу конфликт во время svn update он вставляет kdiff3 вместо того, чтобы копировать весь файл с маркерами конфликта ">>>>>>>>", которые так трудно разрешить, если у вас сложные конфликты. Diff3-cmd работает как для слияния, так и для обновления.

я добавить diff3-cmd = /usr/local/bin/svndiff3 в ~/.subversion/config (или использовать --diff3-cmd на cmdline), так как я написал свой собственный скрипт для отправки svn diff к sdiff и определяется --diff-cmd,

Этот скрипт размещен на yolinux, а слегка измененная версия (которая обрабатывает автоматическое объединение) размещена здесь Jawspeak.

Другие вопросы по тегам