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

Posted

技术标签:

【中文标题】如何将 kdiff3 设置为 SVN 的合并工具【英文标题】:How to set kdiff3 as merge tool for SVN 【发布时间】:2011-06-15 18:56:41 【问题描述】:

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

【问题讨论】:

【参考方案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,但它不起作用),所以它通常用一个简单的脚本调用来翻译参数,例如,“ kdiff3caller":

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

here解释了这个kdiff3问题和解决方案。

【讨论】:

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

一种更短且适用于更高版本 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】:

我在不记得的地方找到了这个脚本。但作者是 Michael Bradley。

我的回答类似于 Jon Ander Ortiz Durántez 的回答。因此,如果他的回答不起作用,您有一个备份。我曾经尝试过他建议的方法,但它总是输出一些参数错误,直到我找到解决所有问题的脚本。

创建一个脚本文件并在您的~/.subversion/config 中设置diff-cmd = /path/to/script.sh

#!/bin/bash # 成功合并时返回错误代码 0,如果未解决冲突则返回 1 # 留在结果中。任何其他错误代码都将被视为致命错误。 # 作者:迈克尔·布拉德利 #注意:所有输出都必须使用“1>&2”重定向到标准错误,因为所有标准输出输出都写入输出文件 # 必须在“~/.subversion/config”文件中被subversion调用 # 添加配置:“diff-cmd = /path/to/script/myKdiff3.sh” VDIFF3="kdiff3" 差异3 =“差异3” 差异=“kdiff3” 用户提示 () 阅读答案 案例“$answer”在 "M") 回声 "" 1>&2 echo "尝试将 $baseFileName 与 $DIFF 合并" 1>&2 $VDIFF3 $older $mine $theirs --L1 $labelOlder --L2 $labelMine --L3 $labelTheirs -o $output 1>&2 bLoop=1 如果 [ -f $输出 ];然后 如果 [ -s $输出 ];然后 #输出写入成功 bLoop=0 菲 菲 如果 [ $bLoop = 0 ];然后 猫$输出 rm -f $输出 出口 0 别的 echo "合并失败,重试" 1>&2 菲 ;; “米”) 回声 "" 1>&2 echo "正在尝试自动合并 $baseFileName" 1>&2 diff3 -L $labelMine -L $labelOlder -L $labelTheirs -Em $mine $older $theirs > $output 如果 [ $? = 1];然后 #不能自动合并 rm -f $输出 $VDIFF3 $older $mine $theirs --L1 $labelOlder --L2 $labelMine --L3 $labelTheirs -o $output --auto 1>&2 bLoop=1 如果 [ -f $输出 ];然后 如果 [ -s $输出 ];然后 #输出写入成功 bLoop=0 菲 菲 如果 [ $bLoop = 0 ];然后 猫$输出 rm -f $输出 出口 0 别的 echo "合并失败,重试" 1>&2 菲 别的 #我们可以自动合并,我们已经做到了 猫$输出 rm -f $输出 出口 0 菲 ;; “差异3” | “差异3” | “DIFF3”) 回声 "" 1>&2 回声“差异...” 1>&2 $VDIFF3 $older $mine $theirs --L1 $labelOlder --L2 $labelMine --L3 $labelTheirs 1>&2 ;; “差异” | “差异” | “差异”) 回声 "" 1>&2 回声“差异...” 1>&2 $DIFF $mine $theirs -L $labelMine -L $labelTheirs 1>&2 ;; “一个” | “一种” ) 回声 "" 1>&2 echo "正在接受远程版本的文件..." 1>&2 猫$他们的 出口 0 ;; “我” | “一世” ) 回声 "" 1>&2 echo "保持本地修改..." 1>&2 猫$我的 出口 0 ;; "R" | "r") 回声 "" 1>&2 echo "恢复到基础..." 1>&2 猫 $旧 出口 0 ;; "D" | "d") 回声 "" 1>&2 echo "Runnig diff3..." 1>&2 diff3 -L $labelMine -L $labelOlder -L $labelTheirs -Em $mine $older $theirs #退出并返回diff3的值(必要时写出文件) 退出 $? ;; "S" | "s") 回声 "" 1>&2 echo "保存以备后用..." 1>&2 猫$我的 #Exit with return vaule of 1 强制写入文件 1号出口 ;; “失败” | “失败” | “失败” ) 回声 "" 1>&2 echo "失败..." 1>&2 2号出口 ;; "H" | “H” ) 回声 "" 1>&2 echo "使用选项:" 1>&2 echo " [A]ccept 接受 $labelTheirs 并丢弃本地修改" 1>&2 echo " [D]efault 使用 diff3 合并文件(与 vanilla SVN 的行为相同)" 1>&2 echo " [Fail] 杀死命令(不建议)" 1>&2 echo " [H]elp 打印此消息" 1>&2 echo " [I]gnore 保持本地修改的版本不变" 1>&2 echo " [M]erge 使用 $VDIFF3 手动合并" 1>&2 echo " [m]erge 与 "M" 相同,但如果可能会尝试自动合并" 1>&2 echo " [R]evert 恢复到基本版本 ($labelOlder)" 1>&2 echo " [S]ave 与 'I' 相同,但写出 rold、rnew 和 rmine 文件以供以后处理" 1>&2 echo " [diff] 在做出决定之前键入 'diff' 以区分版本 $labelMine 和 $labelTheirsthe" 1>&2 echo " [diff3] 输入 'diff3' 以在做出决定之前区分所有三个版本" 1>&2 回声 "" 1>&2 ;; * ) echo "'$answer' 不是一个选项,再试一次。" 1>&2 ;; 经社理事会 如果 [ -z $2 ] 然后 echo ERROR: 这个脚本需要被 subversion 调用 1号出口 菲 如果 [ $2 = "-m" ] 然后 #设置变量 标签矿=$4 标签旧=$6 标签他们的=$8 我的=$9 旧=$10 他们的=$11 输出=$9.svnDiff3TempOutput baseFileName=`echo $mine | sed -e "s/.tmp$//"` #提示用户方向 而 [ 1 ] 做 回声 "" 1>&2 echo "$baseFileName 需要合并。" 1>&2 回声 "" 1>&2 回声“你想做什么?” 1>&2 echo "[M]erge [A]ccept [I]gnore [R]evert [D]efault [H]elp" 1>&2 用户提示 完毕 别的 L="-L" #左标签的参数选项 R="-L" #右标签的参数选项 label1=$3 #左标签 label2=$5 #右标签 file1=$6 #左文件 file2=$7 #正确的文件 $DIFF $file1 $file2 $L "$label1" $L "$label2" & #$DIFF $file1 $file2 & #等待命令完成 等待 菲 出口 0

【讨论】:

如果不对引用进行大量修复,该脚本将无法处理带有空格的文件名 - 将对 $older 的引用更改为 "$older" 等。 也许你找到了它here? 试过了,在小牛上不行,打开kidff但是没有文件。 @yvoyer:你能帮帮我吗?!我也按照指南作为您的评论。但我输入命令:kdiff3。它只是打开 kdiff3 应用程序。我也试过:svn diff kdiff3 svnpath。它也不起作用。你能分享一下svn可以检查并与kdiff3合并的命令吗?!非常感谢! @KennyTaiHuynh,对不起,我已经使用 svn 和 kdiff3 为那个mather工作了一段时间。我拥有这些信息的旧电脑早已不复存在。【参考方案4】:

yvoyer 回答的脚本对我来说非常有用,我使用的是 SVN 1.4。我认为 Jon Ander Ortiz Durántez 的先前回答适用于 SVN 1.5 及更高版本,并且此脚本适用于 1.5 之前的 SVN 版本。似乎对 1.5 版的 --diff-cmd 和 --diff3-cmd 进行了更改。比较以下 2 个 SVN 文档中的脚本以了解一些差异:

svnbook.red-bean.com/en/1.4/svn.advanced.externaldifftools & svnbook.red-bean.com/en/1.5/svn.advanced.externaldifftools.

Michael Bradley 的脚本非常有用,因为现在如果我在 svn update 期间遇到冲突,它会进入 kdiff3,而不是使用“>>>>>>>>”冲突标记来吐槽整个文件,这很难如果您有复杂的冲突,请解决。 diff3-cmd 适用于合并和更新。

我将diff3-cmd = /usr/local/bin/svndiff3 添加到~/.subversion/config(或在命令行上使用--diff3-cmd),因为我编写了自己的脚本以将svn diff 发送到sdiff,并且由--diff-cmd 指定。

此脚本发布在yolinux,稍作修改的版本(处理自动合并)发布在Jawspeak。

【讨论】:

以上是关于如何将 kdiff3 设置为 SVN 的合并工具的主要内容,如果未能解决你的问题,请参考以下文章

如何正确使用 KDiff3 与 TortoiseSVN 来解决冲突?

Ubuntu下Git安装图形化代码合并工具kdiff3

KDiff3 可以用于 Visual Studio 2017 中的比较/差异吗?

使用正则表达式自动合并

Kdiff3 不会用 mergetool 命令打开

如何使用Kdiff3作为GIT merge图形化工具