直せたので、スクリプトを差し替え。
ただこの方法だと、差分を取るファイルの文字コードによっては上手く動作しない。私が遭遇したのは、EUC-JP のファイル。
そこで Ruby スクリプトを *NIX なら標準ではいっているであろう sh, tail, sed, awk と同じくターミナルで日本語を使うなら追加で入れているであろう nkf のみ使うシェルスクリプトにしてみた。
当然予め nkf でここの環境標準の文字コードに変換してから、上記サイトのスクリプトに渡してやったり、Ruby スクリプト内でそういった処理をしてやれば問題ないけど、それならここの単機能プログラムを組み合わせてやったほうが楽だし速いだろうなということで。
#!/bin/sh
# git diff で差分をしつつ ed 形式に出力
# ただし ed 形式の正式な形が不明なので付け焼き刃的
case "$(uname)" in
Darwin|*BSD) sed="sed -E";;
*) sed="sed -r";;
esac
opt="--no-color --no-index -U0 "
for arg in "$@"; do
case "$arg" in
-b | --ignore-space-change )
opt="--no-color --no-index -U0 --ignore-space-change "
shift
;;
-* )
echo "No $arg option"
exit 1
;;
*)
esac
done
git --no-pager diff $opt "$1" "$2" \
| tail -n +5 \
| $sed -e 's/^\+/> /g' \
-e 's/^-/< /g' \
| nkf \
| awk 'BEGIN { before="" }
{
now=substr( $0, 0, 1 )
if ( now ~ /@/ ){
split( $0, in_new, "[@+ \t-]+" );
range=in_new[2];
i=index( range, "," );
if ( i == 0 )in_out=range; # , が無かった→加えて範囲指定は必要なし
else{ # , が見つかった
in_out=substr( range, 0, i - 1 );
in_size=substr( range, i + 1, length( range ) - i );
if ( in_size != "0" )in_out=in_out","( in_out + in_size - 1 );#範囲指定は必要あり
}
range=in_new[3];
i=index( range, "," );
if ( i == 0 )new_out=range; # , が無かった→加えて範囲指定は必要なし
else{ # , が見つかった
new_out=substr( range, 0, i - 1 );
new_size=substr( range, i + 1, length( range ) - i );
if ( new_size != "0" )new_out=new_out","( new_out + new_size - 1 );#範囲指定は必要あり
}
if( in_size == "0" )print in_out"a"new_out
else if( new_size == "0" )print in_out"d"new_out
else print in_out"c"new_out
}
else if ( before ~ />/ && now ~ /</ )print "---\n"$0
else if ( before ~ /</ && now ~ />/ )print "---\n"$0
else print $0
before=now
}'
exit 0
まあ問題は、Windows だと Ruby の導入より面倒くさいよな、という点である。
具体的な設定例は、上記サイトを参考にして欲しい。
nkf ではなく iconv を使う方法も考えたけど、変換エラーが起きずに正しいと思われるエンコードが複数でてくるので、nkf を使うことにした。ただ vim から使うだけなら、そもそも nkf でフィルタを掛ける必要はない。差分を取るファイルの文字コードによっては警告が出るが、それもスクリプト下から 3 行目の
}'
を
}' 2> /dev/null
と捨ててやれば良い