27

SVNが競合について通知したときに、kdiff3を使用して競合を解決できるようにしたいと思います。このためのデフォルトツールとして設定するにはどうすればよいですか?

4

4 に答える 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

4つのプレーン引数をサポートしないkdiff3には問題がありますが(SVNは4つのプレーン引数をkdiff3に渡し、機能しません)、通常、引数を変換するために単純なスクリプトで呼び出されます(例:「kdiff3caller」)。

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

このkdiff3の問題と解決策はここで説明されています。

于 2011-01-26T13:02:11.437 に答える
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
于 2014-05-27T10:24:48.900 に答える
3

このスクリプトを思い出せない場所で見つけました。しかし、作者はマイケルブラッドリーです。

私の答えは、JonAnderOrtizDurántezの答えに似ています。したがって、彼の答えがうまくいかない場合は、バックアップがあります。私はかつて彼が提案したようなことを試しましたが、すべてを解決するこのスクリプトが見つかるまで、パラメーターにエラーが常に出力されていました。

スクリプトファイルを作成diff-cmd = /path/to/script.shし、~/.subversion/config

#!/ bin / bash

#マージが成功するとエラーコード0を返し、未解決の競合の場合は1を返します
#結果に残ります。その他のエラーコードは致命的なものとして扱われます。
#著者:マイケルブラッドリー

#NOTE:すべてのstdout出力は出力ファイルに書き込まれるため、すべての出力は「1>&2」でstderrにリダイレクトされる必要があります

#「〜/ .subversion/config」ファイルのsubversionで呼び出す必要があります
#構成を追加: "diff-cmd = /path/to/script/myKdiff3.sh"

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

promptUser()
{{
    答えを読む
    ケース「${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
        if [-f $ output]; それから
            if [-s $ output]; それから
                #outputが正常に書き込まれました
                bLoop = 0
            fi
        fi
        if [$ bLoop = 0]; それから
            cat $ output
            rm -f $ output
            出口0
        そうしないと
            echo "マージに失敗しました、再試行してください" 1>&2
        fi

        ;;

        "m")
        エコー""1>&2
        echo "${baseFileName}を自動マージしようとしています"1>&2
        diff3 -L $ labelMine -L $ labelOlder -L $ labelTheirs -Em $ mine $ older $ theirs> $ output
        if [$?= 1]; それから
            #自動マージできません
            rm -f $ output
            $ VDIFF3 $ older $ mine $ theirs --L1 $ labelOlder --L2 $ labelMine --L3 $ labelTheirs -o $ output --auto 1>&2
            bLoop = 1
            if [-f $ output]; それから
                if [-s $ output]; それから
                    #outputが正常に書き込まれました
                    bLoop = 0
                fi
            fi
            if [$ bLoop = 0]; それから
                cat $ output
                rm -f $ output
                出口0
            そうしないと
                echo "マージに失敗しました、再試行してください" 1>&2
            fi
        そうしないと
            #自動マージできますが、すでに実行しています
            cat $ output
            rm -f $ output
            出口0
        fi
        ;;

        「diff3」| 「Diff3」| 「DIFF3」)
        エコー""1>&2
        echo "Diffing ..." 1>&2
        $ VDIFF3 $ older $ mine $ theirs --L1 $ labelOlder --L2 $ labelMine --L3 $ labelTheirs 1>&2
        ;;

        「diff」| 「差分」| 「DIFF」)
        エコー""1>&2
        echo "Diffing ..." 1>&2
        $ DIFF $ mine $ theirs -L $ labelMine -L $ labelTheirs 1>&2
        ;;

        「A」| "a")
        エコー""1>&2
        echo"ファイルのリモートバージョンを受け入れています..."1>&2
        猫${彼ら}
        出口0
        ;;

        「私」| "私" )
        エコー""1>&2
        echo"ローカル変更を保持しています..."1>&2
        猫${mine}
        出口0
        ;;

        「R」| "r")
        エコー""1>&2
        echo"ベースに戻しています..."1>&2
        猫${older}
        出口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
        猫${mine}
        #1の戻り値で終了して、ファイルの書き込みを強制します
        出口1
        ;;

        「失敗」| 「失敗」| "不合格" )
        エコー""1>&2
        echo "Failing ..." 1>&2
        出口2
        ;;

        「H」| "h")
        エコー""1>&2
        echo "USAGE OPTIONS:" 1>&2
        echo "[A] ccept $ labelTheirsを受け入れ、ローカルの変更を破棄します" 1>&2
        echo "[D] efault diff3を使用してファイルをマージします(バニラSVNと同じ動作)" 1>&2
        echo "[失敗]コマンドを強制終了します(推奨されません)" 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'と入力して、決定を行う前に3つのバージョンすべてを比較します" 1>&2
        エコー""1>&2
        ;;

        *)
        echo"'${answer}'はオプションではありません。再試行してください。" 1>&2
        ;;
    esac
}

if [-z $ 2]
それから
    エコーエラー:このスクリプトは、Subversionによって呼び出されることを想定しています
    出口1
fi

if [$ 2 = "-m"]
それから
    #Setup vars
    labelMine = $ {4}
    labelOlder = $ {6}
    labelTheirs = $ {8}
    mine = $ {9}
    old = $ {10}
    theirs = $ {11}
    output = $ {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
        promptUser
    終わり
そうしないと
    L = "-L"#左ラベルの引数オプション
    R = "-L"#右ラベルの引数オプション
    label1 = $ 3#左ラベル
    label2 = $ 5#右ラベル
    file1 = $ 6#左ファイル
    file2 = $ 7#右ファイル

    $ DIFF $ file1 $ file2 $ L "$ label1" $ L "$ label2"&
    #$ DIFF $ file1 $ file2&
    #コマンドが終了するのを待つ
    待つ
fi
出口0
于 2011-01-26T22:16:06.003 に答える
3

yvoyerの回答のスクリプトは私にとって非常にうまく機能し、SVN1.4を使用しています。Jon AnderOrtizDurántezからの以前の回答はSVN1.5以降で機能し、このスクリプトは1.5より前のSVNバージョンで機能すると思います。バージョン1.5では--diff-cmdと--diff3-cmdに変更があったようです。次の2つのSVNドキュメントのスクリプトを比較して、いくつかの違いを確認してください。

Michael Bradleyのスクリプトは、svn update複雑な競合がある場合に解決が非常に難しい「>>>>>>>>」競合マーカーを使用してファイル全体をバーフィングする代わりに、kdiff3で競合が発生した場合に、非常に便利です。 。diff3-cmdは、マージと更新の両方で機能します。

sdiffに送信する独自​​のスクリプトを作成し、で指定されているため、diff3-cmd = /usr/local/bin/svndiff3に追加~/.subversion/config(またはコマンドラインで使用)します。--diff3-cmdsvn diff--diff-cmd

このスクリプトはyolinuxに投稿されており、わずかに変更されたバージョン(自動マージを処理する)がJawspeakに投稿されています。

于 2011-12-02T05:02:40.000 に答える