Show base in fugitive.vim conflict diff

2019-02-17 13:46发布

问题:

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.

回答1:

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



回答2:

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.



回答3:

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.



回答4:

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.