Я хотел бы разрешать конфликты с помощью kdiff3, когда SVN уведомляет меня о конфликте. Как я могу установить его как инструмент по умолчанию для этого?
Как установить kdiff3 в качестве инструмента слияния для SVN
Ответ 1
Перейдите в конфигурационный файл 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, и это не работает), поэтому его обычно вызывают с помощью простого script для перевода аргументов, например, "kdiff3caller":
#!/bin/sh
kdiff3 "$1" "$2" "$3" -o "$4"
Эта проблема и решение kdiff3 объясняются здесь.
Ответ 2
Решение, которое короче и работает с более поздними версиями SVN (проверено на SVN 1.7.7):
Создайте script ~/svn-merge-kdiff
#!/bin/bash
# Useful when something fails
LOG=~/svn-merge-kdiff-last-run.log
echo "arguments passed to $0: [email protected]" > $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 [email protected]; 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
Ответ 3
Я нашел этот script, где-то я не могу вспомнить. но автор - Майкл Брэдли.
Мой ответ похож на ответы Джона Андера Ортиса Дюрантеса. Поэтому, если его ответ не работает, у вас есть резервная копия. Я когда-то пробовал что-то вроде этого, но он всегда выдает некоторую ошибку с параметрами, пока не найду эти скрипты, которые разрешили все.
Создайте файл script и установите diff-cmd = /path/to/script.sh
в ~/.subversion/config
#!/bin/bash # Return an errorcode of 0 on successful merge, 1 if unresolved conflicts # remain in the result. Any other errorcode will be treated as fatal. # Author: Michael Bradley #NOTE: all output must be redirected to stderr with "1>&2" as all stdout output is written to the output file # Must be called by subversion in "~/.subversion/config" file # Add config : "diff-cmd = /path/to/script/myKdiff3.sh" VDIFF3="kdiff3" DIFF3="diff3" DIFF="kdiff3" promptUser () { read answer case "${answer}" in "M" ) echo "" 1>&2 echo "Attempting to merge ${baseFileName} with ${DIFF}" 1>&2 $VDIFF3 $older $mine $theirs --L1 $labelOlder --L2 $labelMine --L3 $labelTheirs -o $output 1>&2 bLoop=1 if [ -f $output ]; then if [ -s $output ]; then #output succesfully written bLoop=0 fi fi if [ $bLoop = 0 ]; then cat $output rm -f $output exit 0 else echo "Merge failed, try again" 1>&2 fi ;; "m" ) echo "" 1>&2 echo "Attempting to auto-merge ${baseFileName}" 1>&2 diff3 -L $labelMine -L $labelOlder -L $labelTheirs -Em $mine $older $theirs > $output if [ $? = 1 ]; then #Can't auto merge rm -f $output $VDIFF3 $older $mine $theirs --L1 $labelOlder --L2 $labelMine --L3 $labelTheirs -o $output --auto 1>&2 bLoop=1 if [ -f $output ]; then if [ -s $output ]; then #output succesfully written bLoop=0 fi fi if [ $bLoop = 0 ]; then cat $output rm -f $output exit 0 else echo "Merge failed, try again" 1>&2 fi else #We can automerge, and we already did it cat $output rm -f $output exit 0 fi ;; "diff3" | "Diff3" | "DIFF3" ) echo "" 1>&2 echo "Diffing..." 1>&2 $VDIFF3 $older $mine $theirs --L1 $labelOlder --L2 $labelMine --L3 $labelTheirs 1>&2 ;; "diff" | "Diff" | "DIFF" ) echo "" 1>&2 echo "Diffing..." 1>&2 $DIFF $mine $theirs -L $labelMine -L $labelTheirs 1>&2 ;; "A" | "a" ) echo "" 1>&2 echo "Accepting remote version of file..." 1>&2 cat ${theirs} exit 0 ;; "I" | "i" ) echo "" 1>&2 echo "Keeping local modifications..." 1>&2 cat ${mine} exit 0 ;; "R" | "r" ) echo "" 1>&2 echo "Reverting to base..." 1>&2 cat ${older} exit 0 ;; "D" | "d" ) echo "" 1>&2 echo "Runnig diff3..." 1>&2 diff3 -L $labelMine -L $labelOlder -L $labelTheirs -Em $mine $older $theirs #Exit with return vaule of the diff3 (to write out files if necessary) exit $? ;; "S" | "s" ) echo "" 1>&2 echo "Saving for later..." 1>&2 cat ${mine} #Exit with return vaule of 1 to force writting of files exit 1 ;; "Fail" | "fail" | "FAIL" ) echo "" 1>&2 echo "Failing..." 1>&2 exit 2 ;; "H" | "h" ) echo "" 1>&2 echo "USAGE OPTIONS:" 1>&2 echo " [A]ccept Accept $labelTheirs and throw out local modifications" 1>&2 echo " [D]efault Use diff3 to merge files (same behavior as vanilla SVN)" 1>&2 echo " [Fail] Kills the command (not suggested)" 1>&2 echo " [H]elp Print this message" 1>&2 echo " [I]gnore Keep your locally modified version as is" 1>&2 echo " [M]erge Manually merge using ${VDIFF3}" 1>&2 echo " [m]erge Same as "M" but attempts to automerge if possible" 1>&2 echo " [R]evert Revert to base version (${labelOlder})" 1>&2 echo " [S]ave Same as 'I' but writes out rold, rnew, and rmine files to deal with later" 1>&2 echo " [diff] Type 'diff' to diff versions $labelMine and $labelTheirsthe before making a descision" 1>&2 echo " [diff3] Type 'diff3' to diff all three versions before making a descision" 1>&2 echo "" 1>&2 ;; * ) echo "'${answer}' is not an option, try again." 1>&2 ;; esac } if [ -z $2 ] then echo ERROR: This script expects to be called by subversion exit 1 fi if [ $2 = "-m" ] then #Setup vars labelMine=${4} labelOlder=${6} labelTheirs=${8} mine=${9} older=${10} theirs=${11} output=${9}.svnDiff3TempOutput baseFileName=`echo $mine | sed -e "s/.tmp$//"` #Prompt user for direction while [ 1 ] do echo "" 1>&2 echo "${baseFileName} requires merging." 1>&2 echo "" 1>&2 echo "What would you like to do?" 1>&2 echo "[M]erge [A]ccept [I]gnore [R]evert [D]efault [H]elp" 1>&2 promptUser done else L="-L" #Argument option for left label R="-L" #Argument option for right label label1=$3 #Left label label2=$5 #Right label file1=$6 #Left file file2=$7 #Right file $DIFF $file1 $file2 $L "$label1" $L "$label2" & #$DIFF $file1 $file2 & #wait for the command to finish wait fi exit 0
Ответ 4
script от ответа yvoyer отлично работает для меня, и я использую SVN 1.4. Я думаю, что предыдущий ответ от Jon Ander Ortiz Durántez работает для SVN 1.5 и выше, и этот script работает для версий SVN до 1.5. Похоже, что для версии 1.5 были внесены изменения в -diff-cmd и -diff3-cmd. Сравните скрипты в следующих двух документах SVN, чтобы увидеть некоторые отличия:
- svnbook.red- bean.com/ru/ 1.4/svn.advanced.externaldifftools& Амп;
- svnbook.red- bean.com/ru/ 1.5/svn.advanced.externaldifftools.
Майкл Брэдли script действительно полезен, так как теперь, если я получаю конфликт во время svn update
, он запускается в kdiff3 вместо того, чтобы barfing по всему файлу с " → → → → " маркерами конфликтов, которые так трудно решить, если у вас есть сложные конфликты. Diff3-cmd работает как для слияния, так и для обновления.
Я добавляю diff3-cmd = /usr/local/bin/svndiff3
в ~/.subversion/config
(или использую --diff3-cmd
в cmdline), так как я написал свой собственный script для отправки svn diff
в sdiff и указан --diff-cmd
.
Этот script размещен на yolinux, а небольшая измененная версия (которая обрабатывает автоматическое слияние) размещена здесь Jawspeak.