PolicyStat's Dev Blog

Using Vim as Your Git Mergetool

Resolving merge conflicts has always been a pain point for our team and it’s mostly been a tooling problem.

Not-good-enough Solutions

Until now, we’ve been stuck making tradeoffs between good 3-way diff tools and good code editors.

On one side, tools like Meld are great at showing you the differences, and helping you resolve your text conflict. You lose all your nice editing shortcuts and syntax highlighting though, and you’re dropping out of your normal vim-based workflow.

On the other side, you can use vim or vimdiff, but vim isn’t a merge tool and vimdiff feels clunky for the 3-way merges that git gives you.

Inspiration: fugitive.vim and git mergetool

Today, I read a post by Flaviu Simihaian explaining how to resolve git merge conflicts with Vim. Eureka! You get to stay in your familar editor while keeping all of the niceties of a 3-way diff!

A little nicer via git mergetool

I have one more step to add to make the normal workflow a little easier. Git actually gives you the ability to define arbitary merge tool command for use when resolving merge conflicts, so let’s use that plus the power of vim to change your merge work flow to a simple

$ git merge
$ git mergetool

Configuring mergetool

We’re goingto use the magic of VIM startup commands combined with git-mergetool to automate loading the appropriate diffs inside vim with fugitive.vim’s 3-way merging awesomeness.

Install fugitive.vim

The fugitive.vim plugin gives you access to git commands and information from inside vim. It has the handy ability to do a 3-way git-style diff.

Assuming you have pathogen.vim installed (you should), just run:

$ cd ~/.vim/bundle
$ git clone git://github.com/tpope/vim-fugitive.git

Configure gvim as your mergetool.

$ git config merge.tool gvim
$ git config mergetool.gvim.cmd 'gvim "+Gdiff" $MERGED'


Flaviu’s post has great instructions on usage, but the gist is to use ]c to navigate to conflicts and then :diffget //2 or :diffget //3 to choose the version to keep. :diffupdate fixes your whitespace issues and then :only lets you see what you’ve changed before you save.