如何将kdiff3设置为SVN的合并工具

27

当SVN通知我冲突时,我希望能够使用kdiff3解决冲突。如何将其设置为默认工具?

4个回答

31

前往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问题和解决方案在这里有详细说明。


1
为了处理包含空格的文件名,使用 kdiff3 "$1" "$2" "$3" -o "$4" - hlovdal
2
对我来说,kdiff3启动得很好,但似乎不起作用。当我进行svn合并时,如果有冲突,我会选择“launch(l)”,它会打开kdiff3,但是合并似乎不起作用。它保存到.svn / tmp,但svn合并命令只是重复自己,再次询问我该怎么做。编辑:好的,我的错。它确实起作用,但您需要先进行(l)启动,执行合并,然后选择(r)已解决。 - PapaFreud
1
我想补充一点,更改 /etc/subversion/config 将会更改每个用户的默认设置。如果你只想更改自己的默认设置(或者你没有权限更改全局配置文件),你可以编辑 $HOME/.subversion/config(在 Unix 系统中)或 %appdata%\subversion\config(在 Windows 中)。在这种情况下,不要忘记将选项放在 [helpers] 部分下面。 - Marco Righele
在解决合并冲突的过程中,kdiff3似乎表现得非常出色。现在,我想将kdiff3设置为我的SVN差异工具,但是在我的svn配置文件中使用diff-cmd = kdiff3ForSvn似乎没有执行正确操作(它看起来像是尝试自动合并)。有人尝试过仅使用kdiff3进行差异查看吗? - blong
我可以将此脚本用于“svn update”冲突吗?它将具有不同的文件集:file.mine、file.rOLDREV和file.rNEWREV。 - Shuman

4
一种更短且适用于较新版本 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

把它绑定到~/.subversion/config中的svn

diff3-cmd = ~/svn-merge-kdiff

3
我在某个地方找到了这个脚本,但我记不清作者是谁了。我的答案与Jon Ander Ortiz Durántez的答案类似。所以如果他的答案不起作用,你有备选方案。我曾尝试过像他建议的那样做,但它总是输出一些带参数的错误,直到我找到了这些脚本,解决了所有问题。
创建一个脚本文件,并在您的~/.subversion/config中设置diff-cmd = /path/to/script.sh
#!/bin/bash
# 在成功合并时返回错误代码0,在结果中仍存在未解决的冲突时返回1。任何其他错误代码都将被视为致命的。 # 作者:Michael Bradley
#注意:所有输出必须重定向到stderr,使用"1> &2",因为所有stdout输出都写入输出文件
#必须由subversion在“~/.subversion/config”文件中调用 #添加配置:"diff-cmd = /path/to/script/myKdiff3.sh"
VDIFF3="kdiff3" DIFF3="diff3" DIFF="kdiff3" promptUser() { read answer case "${answer}" in
"M") echo "" >&2 echo "尝试使用${DIFF}合并${baseFileName}" >&2 $VDIFF3 $older $mine $theirs --L1 $labelOlder --L2 $labelMine --L3 $labelTheirs -o $output >&2 bLoop=1 if [ -f $output ]; then if [ -s $output ]; then #输出成功写入 bLoop=0 fi fi if [ $bLoop = 0 ]; then cat $output rm -f $output exit 0 else echo "合并失败,请重试" >&2 fi ;;
"m") echo "" >&2 echo "尝试自动合并${baseFileName}" >&2 diff3 -L $labelMine -L $labelOlder -L $labelTheirs -Em $mine $older $theirs > $output if [ $? = 1 ]; then #无法自动合并 rm -f $output $VDIFF3 $older $mine $theirs --L1 $labelOlder --L2 $labelMine --L3 $labelTheirs -o $output --auto >&2 bLoop=1 if [ -f $output ]; then if [ -s $output ]; then #输出成功写入 bLoop=0 fi fi if [ $bLoop = 0 ]; then cat $output rm -f $output exit 0 else echo "合并失败,请重试" >&2 fi else #我们可以自动合并,而且我们已经做到了 cat $output rm -f $output exit 0 fi ;;
"diff3" | "Diff3" | "DIFF3") echo "" >&2 echo "正在比较..." >&2 $VDIFF3 $older $mine $theirs --L1 $labelOlder --L2 $labelMine --L3 $labelTheirs >&2 ;;
"diff" | "Diff" | "DIFF") echo "" >&2 echo "正在比较..." >&2 $DIFF $mine $theirs -L $labelMine -L $labelTheirs >&2 ;;
"A" | "a") echo "" >&2 echo "接受远程版本的文件..." >&2 cat ${theirs} exit 0 ;;
"I" | "i") echo "" >&2 echo "保留本地修改..." >&2 cat ${mine} exit 0 ;;
"R" | "r") echo "" >&2 echo "恢复到基本版本..." >&2 cat ${older} exit 0 ;;
"D" | "d") echo "" >&2 echo "运行diff3..." >&2 diff3 -L $labelMine -L $labelOlder -L $labelTheirs -Em $mine $older $theirs #以diff3的返回值退出(如果需要写出文件) exit $? ;;
"S" | "s") echo "" >&2 echo "保存以后处理..." >&2 cat ${mine} #返回1以强制写入文件 exit 1 ;;
"Fail" | "fail" | "FAIL") echo "" >&2 echo "

那个脚本如果不进行大量修复引用,就无法处理带有空格的文件名 -- 需要将对 $older 的引用更改为 "$older" 等等。 - Charles Duffy
1
也许你在这里找到了它:https://negativesum.net/tech/log/using-kdiff3-with-svn/? - Adam Spiers
尝试过了,但在Mavericks上无法运行,打开了Kidff但没有文件。 - ronnyfm
@yvoyer: 你能帮我吗?我也按照您的评论所提供的指南。但是我输入命令:kdiff3,它只是打开了kdiff3应用程序。我还尝试了:svn diff kdiff3 svnpath。它也不起作用。您能分享一下svn可以检查和合并kdiff3的命令吗?非常感谢! - Kenny Tai Huynh
@KennyTaiHuynh,很抱歉我已经有一段时间没有使用svn和kdiff3了。我的旧电脑上的这些信息早已不复存在。 - yvoyer
@yvoyer:好的,谢谢你的回复。 :) - Kenny Tai Huynh

3

yvoyer的答案中的脚本对我很有效,我正在使用SVN 1.4。我认为Jon Ander Ortiz Durántez之前的答案适用于SVN 1.5及更高版本,而此脚本适用于1.5之前的SVN版本。似乎在1.5版中对--diff-cmd和--diff3-cmd进行了更改。请比较以下2个SVN文档中的脚本以查看一些差异:

迈克尔·布拉德利(Michael Bradley)的脚本非常有用,因为现在如果我在svn update期间遇到冲突,它会启动kdiff3而不是在文件中吐出">>>>>>>>"冲突标记,这些标记如果你有复杂的冲突是非常难以解决的。 diff3-cmd适用于合并和更新。
我将diff3-cmd = /usr/local/bin/svndiff3添加到~/.subversion/config(或在命令行上使用--diff3-cmd),因为我编写了自己的脚本将svn diff发送到sdiff,并由--diff-cmd指定。
该脚本发布在yolinux,这里发布了一个稍微修改过的版本(可以处理自动合并)Jawspeak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接