← Vim研究所

Vimでファイル間の差分をマージする(:diffget / :diffput)

2019-12-04 公開 ・ 更新: 2026-08-20

差分を見比べるだけでなく、その場でどちらかの内容を採用してマージしたいことがあります。diff表示の状態から使える:diffget/:diffputを覚えておくと、コピー&ペーストで手作業マージするより速く正確に進められます。

目次(11項目)
キーこれだけ覚える
do相手の変更を取り込む(diffget)
dp自分の変更を渡す(diffput)
[c / ]c前 / 次の差分箇所へ移動

前提:diff表示の状態にしておく

ここで紹介するコマンドは、複数のファイルをdiff機能で比較している状態が前提になります。比較の開始方法はファイル間の差分表示の記事を参照してください。

相手の変更を取り込む::diffget

:diffget
:diffg

カーソルのある差分箇所について、もう一方のバッファの内容を今のバッファに取り込みます(上書きします)。「diffで今のバッファにget(取得)する」と覚えると分かりやすくなります。同じ動作をするキーバインドもあります。

do

doは「diff obtain」の略で、d+gではない点に注意してください。連続した行であれば、1回の実行でまとめて取り込めます。

BEFORE
function greet() {
  console.log('hi');
}
do
AFTER
function greet() {
  console.log('hello');
}

もう一方のバッファではconsole.log('hello')となっており、その内容がそのまま取り込まれます。

要点:相手から取り込むなら:diffgetまたはdo。自分から渡すなら:diffputまたはdp。ペアで覚えると混同しにくくなります。
vimdiffで2つのPythonファイルを左右に並べた画面。2行目と3行目に差分があり、変わった部分だけが濃い色で示されている
Vim 9.1.1752。vimdiff local.txt remote.txt の画面。行の中で変わった部分だけ色が濃くなる

自分の変更を渡す::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文字違いで方向が逆になるコマンドなので、最初は緊張しながら実行していましたが、慣れると迷わず打てるようになりました。

3方向の差分では取り込み先を指定する

Gitのコンフリクト解決のように3つのウィンドウが並んでいるときは、dodp だけでは取り込み元が決まりません。:diffget:diffput にバッファ番号を渡して指定します。

:diffget LOCAL      " 自分側の変更を取り込む
:diffget REMOTE     " 相手側の変更を取り込む
:diffget BASE       " 変更前の状態を取り込む

名前が使えるのは、Gitのmergetoolとして起動した場合です。そうでないときは :ls でバッファ番号を調べて :diffget 3 のように渡します。範囲を指定すれば、差分の一部だけを取り込むこともできます。

取り込んだあとに差分を取り直す

編集しているうちに差分の表示が実際の内容とずれることがあります。Vimは編集のたびに差分を計算し直しますが、外部で書き換えられた場合などは追随しません。

:diffupdate       " 差分を計算し直す
:diffoff!         " 全ウィンドウの差分表示を解除

表示がおかしいと感じたら、まず :diffupdate を打ってください。これで直らなければ、実際に内容がずれています。

解決したかを確かめてから終わる

マージを終える前に、取り込み漏れが無いかを確かめます。]c を押して差分が残っていないか、コンフリクトの目印が本文に残っていないかの2点です。

]c                      " 次の差分へ(無ければメッセージが出る)
/^<<<<<<<\|^=======\|^>>>>>>>   " 目印が残っていないか探す

目印が本文に残ったまま保存すると、そのままコミットされてしまいます。差分の見方そのものはファイル間の差分表示にまとめているので、あわせて確認してください。

まとめ

diffマージはdo(相手から取り込む)とdp(自分から渡す)の2つを軸に、[c/]cで差分箇所を移動しながら進めます。手作業のコピー&ペーストより速く、取り違えの事故も少なくなります。取り違えてdodpを逆に押しても、差分モード中の変更は通常のバッファと同じなのでundoでそのまま戻せます。

関連記事

← Vim研究所 トップへ戻る