Vimでファイル間の差分をマージする(:diffget / :diffput)
差分を見比べるだけでなく、その場でどちらかの内容を採用してマージしたいことがあります。diff表示の状態から使える:diffget/:diffputを覚えておくと、コピー&ペーストで手作業マージするより速く正確に進められます。
目次(7項目)
| キー | これだけ覚える |
|---|---|
| do | 相手の変更を取り込む(diffget) |
| dp | 自分の変更を渡す(diffput) |
| [c / ]c | 前 / 次の差分箇所へ移動 |
前提:diff表示の状態にしておく
ここで紹介するコマンドは、複数のファイルをdiff機能で比較している状態が前提になります。比較の開始方法はファイル間の差分表示の記事を参照してください。
相手の変更を取り込む::diffget
:diffget
:diffg
カーソルのある差分箇所について、もう一方のバッファの内容を今のバッファに取り込みます(上書きします)。「diffで今のバッファにget(取得)する」と覚えると分かりやすくなります。同じ動作をするキーバインドもあります。
do
doは「diff obtain」の略で、d+gではない点に注意してください。連続した行であれば、1回の実行でまとめて取り込めます。
function greet() {
console.log('hi');
}
function greet() {
console.log('hello');
}
もう一方のバッファではconsole.log('hello')となっており、その内容がそのまま取り込まれます。
:diffgetまたはdo。自分から渡すなら:diffputまたはdp。ペアで覚えると混同しにくくなります。自分の変更を渡す::diffput
:diffput
:diffpu
今のバッファの、カーソルがある差分箇所の内容を、もう一方のバッファへ反映します。キーバインドは次のとおりです。
dp
dpは「diff put」の略で、コマンド名の:diffputとそのまま対応しているためdoより覚えやすくなります。
差分箇所を移動しながらマージする
[c " 前の差分箇所へ
]c " 次の差分箇所へ
実務では]cで次の差分へ移動し、内容を確認してからdoまたはdpでマージする、という流れを繰り返すことになります。この4つのキーはセットで覚えておくと作業が滑らかに進みます。
ただし、この流れが使えるのはテキストファイルの差分に限られます。画像やzipのようなバイナリファイルはそもそもdiff表示ができないため、行単位で取り込むのではなくどちらの版を採用するかをGit側で指定する形になります。
パッチファイルをマージする
:diffpatch パッチファイルのパス
:diffp パッチファイルのパス
パッチファイルの内容を、現在のバッファにマージできます。利用機会は多くありませんが、diffコマンドで生成したパッチを手元のファイルに適用したいときに使えます。
3ファイル以上を比較しながらマージする
:diffget/:diffputは、開いているウインドウが3つ以上ある場合にも使えます。その場合、引数にバッファ名やバッファ番号を指定することで、どのウインドウから取得・どのウインドウへ反映するかを明示できます。
:diffget バッファ名
:diffput バッファ名
引数を省略した場合は、カレントウインドウに隣接する(水平・垂直に並んだ)ウインドウが自動的に対象になります。3方向マージのように複数の版を見比べながら統合したい場面では、この引数指定が役立ちます。
2つの環境で少しずつ育ってしまった設定ファイルを1つにまとめる作業で、diffgetとdiffputを使うようになってから、コピー&ペーストで取り違えるミスがなくなりました。特にdoとdpは1文字違いで方向が逆になるコマンドなので、最初は緊張しながら実行していましたが、慣れると迷わず打てるようになりました。
まとめ
diffマージはdo(相手から取り込む)とdp(自分から渡す)の2つを軸に、[c/]cで差分箇所を移動しながら進めます。手作業のコピー&ペーストより速く、取り違えの事故も少なくなります。