git on wsl での WinMerge

先天的迷子ネタにつき、混乱にご注意。

ひとつに、wsl ファイルシステムで TortoiseGit が使えなくて困っていた。そちらの解決方法はそれはそれとして。この正解に至る前に、そもそも「TortoiseGit が使えないから仕方なく wsl コマンドラインで、として、それでも git を駆使するのがまぁ苦でないとしても、差異をビジュアルに見れて、なおかつ、その場で編集できないのが一番困る(≒ WinMerge が使えないことが一番困る)」と考えるわけだ。そもそも wsl では、設定変更しない限りは Windows の exe をそのまま動かせるので、出来なきゃおかしいだろう、と。ところがこれがまぁまぁ苦労させられた。

いつも通り答えだけ書くと簡単なわけよな:

.gitconfig
1 [diff]
2         tool = winmerge
3 [difftool "winmerge"]
4         cmd = "winmerge.sh \"$LOCAL\" \"$REMOTE\""
5 [difftool]
6         prompt = false
winmerge.sh
1 #! /bin/sh
2 cmp -s "$1" "$2" && exit 0
3 lhs=$(echo "$1" | sed 's@/@\\@')  # assuming that $1 is such as "/tmp/xxx"
4 rhs="$2"
5 WinMergeU.exe -e -u -dl "Local" -dr "Remote" "${lhs}" "${rhs}"

.gitconfig の編集は git config コマンドで行えるけれど、エスケープの扱いとかダルいので、直接編集しちゃう方が楽だと思うよ、場所さえ知ってるなら。

問題はラッパースクリプトの winmerge.sh でな。これがまぁ「windows であり linux であり、linux なのに windows、windows なのに linux」な繊細さの影響をモロに受けちゃうのですわ。引数の左辺($1)を「詐称」する必要があるのはこれは、WinMergeU.exe が「/ で始まる文字列」をオプションだと認識してしまうことへの措置。すなわち「/tmp/xxx」として渡ってくるのを「\tmp/xxx」に置換しなければならぬ、と。まぁややこしいわ、だってねぇ、これさえやっとけば、あとはちゃんと「\\wsl.localhost\Ubuntu\…」が渡されちゃうんだから…。まぁしょうがないかなぁと思うけど、ダルいわ。

winmerge.sh は wsl 上での ~/.local/bin の下とかに置くといいんじゃないかね。当然ながら「linux シェルスクリプト」なので chmod はお忘れなく。MSYS にばかり慣れてるとつい忘れがちになるけど。

で、こうしておけば、たとえば「git difftool .」で差異を WinMerge で参照(編集)出来る。

TortoiseGit に期待するのはビジュアル diff の件だけでなく例えば revert の楽さだったりとかいろいろあるのでこれを使えるようにするのが最善なのだけれど、少なくとも私にとって最も致命傷なのが diff の件なので、正直これだけで「TortoiseGit は諦めてもいいか」とすら思う。git コマンドそのものは、大抵は「慣れればいい」だけだからね…。


2023-04-22追記:
ひとんちからパクってきたときは気を付けんとなぁ。上の winmerge.sh だとめっちゃ使いにくいのだ。なんでファイル名を見えなくしちゃうのよ、てことで:

winmerge.sh
1 #! /bin/sh
2 cmp -s "${1}" "${2}" && exit 0
3 lhs=$(echo "$1" | sed 's@/@\\@')  # assuming that $1 is like "/tmp/xxx"
4 rhs="${2}"
5 WinMergeU.exe -e -u -dl "Local ('${1}')" -dr "Remote ('${2}')" "${lhs}" "${rhs}"
2023-05-26追記:
原因が今一つわからないのだが「Remote」と「Local」が逆になってる気がする。もうね、こうなるとこのほうがマシかも:

winmerge.sh
1 #! /bin/sh
2 cmp -s "${1}" "${2}" && exit 0
3 lhs=$(echo "$1" | sed 's@/@\\@')  # assuming that $1 is like "/tmp/xxx"
4 rhs="${2}"
5 WinMergeU.exe -e -u -dl "${1}" -dr "${2}" "${lhs}" "${rhs}"

あるいは -dl, -dr の指定をやめちゃってもいいかも。余計な読み替えせずとも、/tmp との比較だから識別出来ると思うんよな。



Related Posts