By default if you use fugitive.vim's :Gdiff
on a file buffer which is in conflict with git, you will get a three way diff showing HEAD
, the working copy (with conflict markers), and the merge
.
I like to have git config merge.conflictstyle diff3
set, which includes the base (most recent common ancestor of HEAD
and merge
in the conflict markers.
Unfortunately even with diff3
as the conflictstyle
in fugitive.vim you still only get 3 panes (no base).
Does anyone know how to make show it in another pane? Ideally about the working copy.
This comment from Tim Pope seems to provide some clue, but I can't quite figure it out.
You can do it with the following steps:
:split
- Do a horizontal split
:Gdiff
- Diff in the top window
- ctrlw + j - Move focus to bottom window
Gedit :1
- Load ancestor in bottom window
Gedit :2
loads head and Gedit :3
loads the merge
The quickest way I know of is this command, issued in the conflicted buffer:
:Gsdiff :1 | Gvdiff
You must enter these commands as a one-liner, the effect is different when you enter them as two separate commands.
The result looks like this:
+---------------------------------------+
| common ancestor (:1) |
+-----------+--------------+------------+
| | | |
| HEAD (:2) | working copy | merge (:3) |
| | | |
+-----------+--------------+------------+
The stuff inside the brackets are the 'revision' specifiers that fugitive.vim understands in this context. See :h fugitive-revision
for more information.
You can use git mergetool -t gvimdiff. It will open 4 windows in gvimdiff. It's not built into fugitive, however still you can use vim to do your 3-way merge.
These answers are all great if you just want to open the diff on a file you already have open in a vim buffer. I prefer using git mergetool
and having that open a 4-way diff view like the following:
+-----------+----------------------+------------+
| | | |
| HEAD (:2) | common ancestor (:1) | merge (:3) |
| | | |
+-----------+----------------------+------------+
| working copy |
+-----------------------------------------------+
Thanks to the other answers here, I was able to make that work by creating a file called diff.vim
and placing it in my ~/.vim
directory:
Gsdiff :1
exe 1 . "wincmd w"
Gvdiff!
call feedkeys(winnr()."\<C-W>jgg", 'n')
Then, just make your mergetool command execute vim -f "$MERGED" -S "$HOME/.vim/diff.vim"
. My ~/.gitconfig
has the following:
[mergetool "fugitive"]
cmd = vim -f "$MERGED" -S "$HOME/.vim/diff.vim"
[merge]
tool = fugitive
Hope this is useful to others out there.