Search code examples
vimvim-fugitive

How to display 'word-level' changes when resolving conflicts with 3-way diff?


Resolving conflicts with fugitive is great. After reading Painless Merge Conflict Resolution in Git, I started to think how to display changes not only on a line-level but also on word-level.

All examples / cases are based on painless_git_conflicts_resolution repo. Hub was used to make git clone command more succinct.

Fugitive with disabled diff3 conflict style.

hub clone ryrych/painless_git_conflicts_resolution fugitive_no_diff3 cd fugitive_no_diff3/ git checkout beta git merge origin/master vim roses.txt :Gdiff

The result is following:

Resolving conflicts with fugitive without diff3 enabled

Problem is that you can only see that all lines changed in some way. This example is very short, but how many of you spotted that of has been added in line 3?

RubyMine can solve that, though not always, leaving you more than often with diff marks, and without diff highlighting. Though on this screen shot there are no diff marks, the lack of 'contrast' makes it very difficult to solve that conflicts.

Resolving conflicts with RubyMine

Fugitive with enabled diff3 + displaying common ancestor:

Show base in fugitive.vim conflict diff stackoverflow question made me try the accepted answer, but the solution wasn't an improvement.

hub clone ryrych/painless_git_conflicts_resolution fugitive_with_diff3 cd fugitive_with_diff3/ git checkout beta git merge origin/master vim roses.txt :split :Gdiff [Ctrl][W][J] :Gedit :1

Resolving conflicts with fugitive without diff3 disabled

opendiff as a mergetool

hub clone ryrych/painless_git_conflicts_resolution opendiff cd opendiff/ git checkout beta git merge origin/master git mergetool

and voilà!

Resolving conflicts with opendiff

This, of course, solves the problem, but makes me rely upon an external tool that was only designed for one system. To sum up: is it possible to achieve something similar in Vim as in opendiff?


Solution

  • I've found that on my machine (running vim 7.4) all the diffs do highlight the differences within lines. The text from :help view-diff implies that this is standard behavior. It says nothing about turning the feature on or off, only that the hl-DiffText highlight group is used for "Changed text inside a Changed line"

    I would try a different color scheme, or at least try and double check that your current color scheme defines an appearance for hl-DiffText

    EDIT: Apparently, the given example is actually really bad for showing word-level differences. Every line has changes in multiple places, they're very short, and there's no lines that remain completely unchanged to provide context. As you can see in the screenshots, removing the conflict marker puts all the "all my base" lines at the same line number, and the word-level differences get highlighted. You might want to try with a more complex repo/merge conflict.

    :Gdiff in vim not showing word-level changes

    :Gdiff in vim showing word-level changes