しおメモ

雑多な技術系ブログです。ニッチな内容が多いです。

git mergeのコンフリクト解消にvimdiffを使う

普段からVimを使うようなその道の人には有名かと思いますが、XcodeやらVSCodeやらを使う人々にとっても、おすすめできるので書いてみました。

自分もiOSやる前はEmacsユーザーで、正直あんまりVimは慣れていないのですが、それでも使いやすいです。

git mergetoolを使う

コンフリクトを解消する際に、エディタを使って該当部分を編集することも可能ですが、 git mergetoolを利用するとコンフリクトした箇所だけを外部ツールで表示してくれるので、素早く編集することが可能です。

vimdiff以外にもVSCodeなど他のツールを利用することもできます。(個人的には、vimdiffが一番シームレスに編集できると感じています)

git mergeの後、git mergetool -t vimdiffを打つことで、vimdiffを利用した編集に移行できます。

毎回利用する場合はgitのaliasや、configを利用すると便利です。

# デフォルトのmergetoolをvimdiffにする
git config --global merge.tool vimdiff

コンフリクト解消の手順

git mergetoolvimdiffを起動すると、このような画面になります。

f:id:scior:20210505192617p:plain

上の画像のように、4つにsplitされた状態で表示され、上半分が左からlocal, base, remoteとなります。 下半分が作業中のファイルです。

vimdiffの操作については、詳しくは:help diffで参照できますが、よく使う操作を軽く解説します。

[c,]cで前後のコンフリクト箇所に移動できます。:diffupdateで再度diffを検出できます。(undo等の操作で崩れやすい)

単純にlocalやremoteの内容をそのまま使う場合、該当箇所でノーマルモードで1do, 3doと打てばよいです。(それぞれ、1番目、3番目のbufferからdiff obtainする意)

より細かいコードの編集が必要な場合は、普通のVimと同じように操作します。 編集が完了した際は、:qaで次のファイルに進めます。

おすすめの設定

デフォルトでgit mergetool.origをつけたバックアップファイルを生成して邪魔になることが多いので、configで無効にするのをおすすめします。

git config --global mergetool.keepBackup false

また、diffのアルゴリズムを変更しておくと、結果が多少賢くなる場合があります。 diffoptalgorithmpatiencehistogramを指定しておくのがおすすめです。(vim 8.1.0360以上のみなので、macユーザーは更新必要なケースあり)

set diffopt+=algorithm:patience,indent-heuristic

大体の言語はデフォルトでsyntax highlightがありますが、Swiftとかは入っていないので、適宜入れておくと捗ります。

デメリット

splitする都合上、画面を広く使えないと厳しいかもしれません。自分はターミナルを縦splitすることが多いので、横幅に困ることがたまにあります。

Vimでの編集は、コンフリクト解消くらいであれば、自分のようなてきとーユーザーでも意外となんとかなります。