Using vimdiff as git mergetool can be pretty confusing. Multiple windows, little explanation. This is a short tutorial to explain basic usage, what do LOCAL, BASE and REMOTE keywords mean. This implies that you have at least very little basic vim knowledge (how to move, save and switch between split windows), if you don’t – there’s a short article for you: Using vim for writing code. Some basic understanding of git and branching is required as well, obviously.
Git config
Prior to doing anything, you need to know how to set vimdiff as a git mergetool. Do:
|
1 2 3 |
git config merge.tool vimdiff git config merge.conflictstyle diff3 git config mergetool.prompt false |
This will set git as default merge tool, will display a common ancestor while merging and will disable the prompt to open the vimdiff.
Creating merge conflict
Let’s create a test situation. You are free to skip this part or you can work along with the tutorial.
|
1 2 3 4 |
mkdir zoo cd zoo git init vi animals.txt |
Let’s add some animals:
|
1 2 3 4 |
cat dog octopus octocat |
Save the file.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
git add animals.txt git commit -m "Initial commit" git branch octodog git checkout octodog vi animals.txt # let's change octopus to octodog git add animals.txt git commit -m "Replace octopus with an octodog" git checkout master vi animals.txt # let's change octopus to octoman git add animals.txt git commit -m "Replace octopus with an octoman" git merge octodog # merge octodog into master |
That’s where we get a merge error:
|
1 2 3 |
Auto-merging animals.txt CONFLICT (content): Merge conflict in animals.txt Automatic merge failed; fix conflicts and then commit the result. |
Resolving merge conflict with vimdiff
Let’s resolve the conflict:
|
1 |
git mergetool |
This looks terrifying at first, but let me explain what is going on.
From left to right, top to the bottom:
LOCAL — this is file from the current branch
BASE — common ancestor, how file looked before both changes
REMOTE — file you are merging into your branch
MERGED — merge result, this is what gets saved in the repo
Let’s assume that we want to keep the “octodog” change (from REMOTE). For that, move to the MERGED file (Ctrl + w, j), move your cursor to a merge conflict area and do:
|
1 |
:diffget RE |
Which gets the corresponding change from the REMOTE and puts it in MERGED file. You can also do
|
1 2 3 |
:diffg RE " get from REMOTE :diffg BA " get from BASE :diffg LO " get from LOCAL |
Save the file, quit (fast way to write and quit multiple files – :wqa).
Run git commit and you are all set!




