mercurialのマージ作業をvimで

GUIの無い環境で開発してると手動マージが発生したときに結構たるい作業を強いられる訳です。

mercurialのデフォルトだと

<<<<<<<<<local
ウオー
==========
うおー
>>>>>>>>>other

なんてのをテキストエディタでちまちま直す必要があるわけで、めんどい。

マージツールつかえよ

vim様にはマージ機能があるというのは前から知ってて使いたかったんだけど、どうも操作がよくわかんなくて放置していました。


ということで、ちょっと真面目に調べてみた。

設定

まずmercurialの設定

hgrcなどにマージツールとしてvimdiffを使う設定を書く

[ui]
merge = vimdiff

使う

confrectが発生するようなマージを行うと、勝手にvimがdiffモードで立ち上がります。

デフォルトでは

マージ結果 | local | other

てな感じに縦3分割されてます。

マージ結果のところにlocalとotherの成果を集めます。

diffの見方とかについては割愛。

作業

下記のコマンドを駆使してよしなにマージしましょう。

diffg[et] buf
カレントバッファにbufからカーソル位置に対応するブロックを引っ張ってくる。
diffpu[t] buf
カレントバッファのカーソル位置のブロックをbufに突っ込む
[c
前の衝突位置へカーソル移動
]c
次の衝突位置へカーソル移動

bufはバッファ番号を指定します。デフォルトのままであれば左から1, 2, 3と番号が振られるので

  1. 結果のところで:diffg 2 = use local
  2. 〃:diffg 3 = use other


という感じ。

終わったら:wqaなどして結果を保存してvimを終了します。

複数のファイルが衝突していた場合、一つ目を閉じると二つ目のvimが現れます。がんばって全部マージして下さい。

全てのマージが終わったらコミットして終了です。

一工夫

上のままでも悪くはないですが

  1. :diffgとか毎度打ってらんない
  2. スクロールめんどい
  3. なんかどんどん表示が崩れていく

などの不満が出ると思います。

なのでこんな感じにmapを書いてみました。

map dl :diffg 2<CR>:diffupdate<CR>]czz
map do :diffg 3<CR>:diffupdate<CR>]czz
map dp :diffp 1<CR>:diffupdate<CR>]czz

dl,doはマージ結果のペインで使用する想定、dpはlocal, otherのペインで使用する想定です。

また崩れ対策の為の:diffupdateの実行、次の衝突箇所へのカーソル移動+カーソル行を画面中央に持ってくる までを一撃で。

総評

わるくないです。ソースに謎の<<<<<<<が残ってしまう事も無くなるし。

まあgui使えるならguiでいいとおもいます。