半年之前就用vimdiff取代了svn的diff(传送门), 但是冲突处理没能用vim实现, 一直耿耿于怀, 这几天终于忍不住收拾了下.

svn处理merge是用的diff3, 顺利合并就返回0, 合并错误就给出选项询问如何解决. 传统的外部工具处理方式也是从这里hook, 比如kdiff3, 先合并, 顺利合并就往下走, 合并错误就出一个用于merging的界面给你编辑, 手动处理后返回0退出.

但是vim并没有实现diff3, 所以hook这里并不合适. 还好, 1.5版的svn引入了交互式的冲突解决方式, 其中有用外部工具处理冲突的”l”. 和你写diff3的wrapper脚本不同的是, 这个只有在diff3不能顺利处理合并的时候才会启动, 容易处理得多, 只需要写个很简单的脚本, 然后将svn配置里的merge-tool-cmd指向它就好.

#!/bin/sh

# Configure your favorite merge program here.
MERGE="vim -d"

if [ -z $2 ]
then
	echo ERROR: This script expects to be called by subversion
	exit 1
fi

# Subversion provides the paths we need as the first, second, third
# and fourth parameters.
BASE=${1}
THEIRS=${2}
MINE=${3}
MERGED=${4}

# Call the merge command (change the following line to make sense for
# your merge program).
$MERGE $MERGED -c ":diffsplit $MINE" -c ":vertical diffsplit $THEIRS" \
	-c ":vertical diffsplit $BASE"

# Return an errorcode of 0 on successful merge, 1 if unresolved conflicts
# remain in the result.  Any other errorcode will be treated as fatal.
exit 0

Enjoy it.