Git Merge Conflicts

Git Diff Highlighting

Git now comes with a useful diff highlighter that highlights both the line and word level changes to files.

When using git add -p the specified script in the interactive.diffFilter variable is called to show differences. This can be set to diff-highlight, so that the output looks the same as git diff.

However, there is a better option when diffing prose, or long, space-less code that is mistakenly interpreted as one word: git diff --color-words .

Unfortunately, this doesn’t work well with the interactive filter. A better solution is to install the diffr script (e.g. brew install diffr) and set the interactive.diffFilter to this.

I have 3 way diffs configured in gitconfig:

[merge]
  conflictstyle = diff3

Clarification

Just to be clear, there is two different things here:

What the file annotations mean

Git nomenclature is pretty poor for this.

Given

[~/blog/branch_a]> git merge branch_b

The current branch, branch_a is known as the target branch. The branch that is to be merged, branch_b is known as the merge branch.

For a two-way diff,:

<<<<< branch_a # target branch: current content of file
file contents
=======
other file contents=
>>>>> branch_b # merge branch: content that needs to be applied

rebase:
original 1
original 2
original 3
<<<<<<< HEAD # the change on the target branch already applied
changed on master 4
changed on master 5
changed on master 6
=======
changed on branch_b 4
changed on branch_b 5
changed on branch_b 6
>>>>>>> 2710110 (Changed on branch_b) # the change on the merge branch you are trying to add
original 7
original 8

For a diff3 style, you have an extra section telling you the shared common ancestor to the conflicting commits. Here is what the three sections are telling you:

original 1
original 2
original 3
<<<<<<< HEAD   # the change on the target branch already applied
changed on master 4
changed on master 5
changed on master 6
||||||| parent of 2710110 (Changed on branch_b)  # the orignal file, the shared common ancestor
original 4
original 5
original 6
=======
changed on branch_b 4
changed on branch_b 5
changed on branch_b 6
>>>>>>> 2710110 (Changed on branch_b)  # the change on the merge branch you are trying to add
original 7
original 8

Vim has a useful plugin - vim-fugitive for dealing with all sorts of git interactions, including a useful difftool mode for managing conflicts. It’s a very effective way of dealing with complicated marge conflicts. I’ve blogged about it: Vim-Fugitive.

Tagged: | git | software-development |
Cover Image: Headway, via Unsplash