vimtricks.wiki Concise Vim tricks, one at a time.

How do I resolve a 3-way merge conflict by pulling changes from a specific buffer in diff mode?

Answer

:diffget 2

Explanation

When Vim's diff mode has three or more buffers open, :diffget (or do) without an argument is ambiguous — Vim cannot determine which buffer to pull from. You must specify the source buffer by number or by a unique fragment of its filename.

How it works

In a typical 3-way merge setup (e.g., :Gdiffsplit! with vim-fugitive, or git mergetool configured to use vimdiff), three source buffers sit alongside your working merge buffer:

  • LOCAL — your local changes
  • BASE — the common ancestor
  • REMOTE — the incoming branch's changes

To pull a hunk from the LOCAL buffer (buffer 2 in a standard fugitive layout), position your cursor on the conflict hunk inside the merge buffer and run:

:diffget 2

Rather than relying on buffer numbers (which vary by session), pass a unique fragment of the buffer's filename:

:diffget LOCAL
:diffget REMOTE
:diffget BASE

Vim matches the fragment case-insensitively against all loaded buffer names and pulls from the unique match.

Example

A fugitive 3-way merge has buffers: REMOTE (2), BASE (3), LOCAL (4), and the working MERGE buffer in focus.

[cursor on conflict hunk in MERGE buffer]
:diffget LOCAL   " pulls LOCAL version of this hunk into MERGE
:diffget REMOTE  " pulls REMOTE version instead

After resolving all hunks:

:diffoff   " exit diff mode
:w         " save the resolved file

Tips

  • Use ]c and [c to jump between conflict hunks without leaving the merge buffer
  • :ls shows buffer numbers if you need to confirm them
  • The normal-mode shorthand do runs :diffget — it requires a count suffix to specify the buffer: 2do
  • :diffput {buf} works in reverse: push the current hunk from the active buffer into another

Next

How do I right-justify a line of text to a specific width using a built-in Vim command?