14 tips and tools to resolve conflicts with Git

December 1st 2015 Nicola Paolucci in Git

Git is very good at merging code. Merges are local, fast, and flexible. Naturally every time one merges content from different branches conflicts can and will happen. Often solving a conflict is as simple as knowing and choosing the leading change. Sometimes resolving a conflict requires more work.

Every developer has a different preference in how they solve conflicts. So a while ago fellow writer Dan Stevens used Questions for Confluence internally to ask how people did it.

Questions on Confluence

The answers and insight collected have much broader appeal than the walls of Atlassian and so below is an expanded and annotated collection of the many ways we solve Git conflicts. Hopefully it will provide ideas and things to try and incorporate in your daily coding practice.

General setup tips

Let's start with a simple set of basic configuration toggles to setup Git properly for merges.

1. Setup tips

When you have a conflict, you can initiate your merge sessions from the command line typing "git mergetool" or from a visual tool. To setup Git with your favorite conflict resolution software use the "merge.tool" variable in ".gitconfig". For example someone using KDiff3 might fill the ".gitconfig" merge section like:

[merge]
tool="kdiff3"

The above is equivalent to typing from the command line:

git config --global merge.tool kdiff3

2. Show common ancestor in conflict markers

Use the following setting to improve the conflict markers to show also the common ancestor (Thanks Robin Stocker and Hugh Giddens):

git config --global merge.conflictstyle diff3

The setting annotates the conflict by adding a new section with marker ||||||| to show how the conflicting lines looked at the commit which is the common ancestor of the two branches in question.

3. Use the "patience" algorithm in merges

If you have lots of conflicts in a long piece of content like an XML file or when two versions have diverged a lot, try merging again using:

git merge --strategy-option=patience

The result of the patience algorithm should help reconcile better the misaligned brackets in functions and tags. Some details on the algorithm can be found on this Stack Overflow answer.

4. When you need information on the history of a single file

Barring using a visual tool like SourceTree to find out what happened to a file you can use:

git log --merge --decorate --source -p path/to/file/you/care/about

Solving conflicts manually

There are two broad schools of thought in working through merges: some developers like to use a low-level process and manipulate conflict markers by hand and some prefer to be aided by a visual tool. Both can be extremely effective.

5. Sample process

Several colleagues shared their manual process, for example Jason Hinch reported his flow:

  • Start with the merge at hand:

    git merge the/other/branch
    git status
  • Have a look at how many/which files conflicted.

  • For each conflicting file:

    • Open the file in editor of choice (i.e. IntelliJ or vim)
    • Look at each block wrapped in conflict markers (">>>>" and "<<<<").
    • See if it makes sense, what was the intention of each author, resolve it if you can figure it out.
    • If the conflict markers don't make sense - often when files have changed significantly - run:

      git diff HEAD...the/other/branch -- path/to/conflicting/file
      git diff the/other/branch...HEAD -- path/to/conflicting/file

      You do this to see which side is the smaller change.

    • Often the commands:

      git log -p HEAD..the/other/branch -- path/to/conflicting/file
      git log -p the/other/branch..HEAD -- path/to/conflicting/file

      can shed further light on what changed on either side.

    • Revert the file to the side which has the most changes:

      git checkout the/other/branch -- path/to/conflicting/file

      (Alternatively you could also use git checkout --theirs or --ours here).

    • Manually go though and reapply the changes performed on the other side to the file:

      git add path/to/conflicting/file
    • When all the changes have been fixed build the project, ensuring that it at least compiles - if the tests are quick to run, run them as well:

      git commit

This may seem a little manual, but Jason found it results in fewer bad merges for his workflow.

For a hands on step by step basic video on how to solve conflicts manually checkout our recent Git Power Routines course.

Git Power Routines

Parade of merge tools

There are many different visual tools to perform complex merge and conflict resolutions. My colleagues have mentioned a wide - non exhaustive - range.

6. IntelliJ IDEA conflict resolution tool

IntelliJ IDEA is the IDE of choice of many Atlassians. Many use the built-in IntelliJ IDEA conflict resolution tool to deal with conflicts. It provides three panes for analysis: local, remote and merge result.

IntelliJ IDEA

7. KDiff3

KDiff3 is part of the KDE product suite and was mentioned a few times in our internal survery.

KDiff3

8. P4Merge

Steve Streeting - original author of SourceTree - and several other colleagues uses P4Merge for merges. P4Merge is a free visual tool and has four panes instead of the three other tools provide. The panes show the "base", "local", "remote" and "merge result".

P4Merge

9. meld

Developed using GTK+ and Python, meld has been around for a long time as well and was mentioned by a few.

Meld

10. tig for status + diff

More terminal oriented folks use tig - we wrote an awesome introduction about tig sometime ago - and regular terminal git diff.

Tig+diff

11. OS X FileMerge aka opendiff

In the long list of suggestions a couple of developers mentioned the native "opendiff" tool from OS X, otherwise named "FileMerge".

Filemerge

12. diffmerge

I don't know much about diffmerge but it was mentioned too in the list.

Diffmerge

13. Araxis Merge (commercial)

This name - Araxis Merge - reminds me of a time long ago when I was working on a locked down Windows machine trying to survive a sea of XML files madness and the tool proved to be up to the challenge. It's a commercial tool.

Araxis Merge

14. vimdiff3

Several colleagues use vimdiff to solve conflicts. That is vim's own merge/diff tool. You can set it up by typing:

git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false

Or directly modifying the .gitconfig file as shown above.

Conclusions

How do you solve conflicts? What is your flow? Do you use any other tool than the ones mentioned? Let us know your tricks, ping me at @durdn or my awesome team at @atlassiandev.  


You might also enjoy our ebook, "Hello World! A new grad's guide to coding as a team" – a collection of essays designed to help new programmers succeed in a team setting. Grab it for yourself, your team, or the new computer science graduate in your life. Even seasoned coders might learn a thing or two.

Read it online now

Click here to download for your Kindle