Как установить 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, чтобы увидеть некоторые различия:
- http://svnbook.red-bean.com/en/1.4/svn.advanced.externaldifftools.html &
- http://svnbook.red-bean.com/en/1.5/svn.advanced.externaldifftools.html.
Сценарий Майкла Брэдли действительно полезен, так как теперь, если я получу конфликт во время svn update
он вставляет kdiff3 вместо того, чтобы копировать весь файл с маркерами конфликта ">>>>>>>>", которые так трудно разрешить, если у вас сложные конфликты. Diff3-cmd работает как для слияния, так и для обновления.
я добавить diff3-cmd = /usr/local/bin/svndiff3
в ~/.subversion/config
(или использовать --diff3-cmd
на cmdline), так как я написал свой собственный скрипт для отправки svn diff
к sdiff и определяется --diff-cmd
,
Этот скрипт размещен на yolinux, а слегка измененная версия (которая обрабатывает автоматическое объединение) размещена здесь Jawspeak.