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
]cand[cto jump between conflict hunks without leaving the merge buffer :lsshows buffer numbers if you need to confirm them- The normal-mode shorthand
doruns: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