Git Merge Tools

Quite often, a line is changed by two parties differently, and one of the versions is merged. The other party should get the changes and resolve the conflict. How do you usually resolve conflicts?

TL;DR

There is a command called git mergetool that helps you resolve conflicts. It opens a merge tool based on your choice. E.g.

git mergetool --tool=vimdiff3

Conflicts

So, what does a conflict look like? Let's take a look at an example:

<<<<<<< HEAD
name: 'auto-assign'
on:
pull_request:
types: [opened, ready_for_review]

jobs:
assign-author:
runs-on: ubuntu-latest
steps:
- uses: kentaro-m/auto-assign-action@v1.2.1
with:
configuration-path: '.github/auto-assign.yml'
=======
*# Nothing is here yet
*>>>>>>> Conflicting commit

This is a file that two parties edited. One of them created some config and merged them into the master branch. The other party just added a single line of comment saying "Nothing is here yet", and committed it, setting "Conflicting commit" as the commit message. Then she rebased her branch onto master, and this conflict happened.

In a nutshell, this part of the code shows two versions of the file on top of each other. So, now, how to resolve it?

Edit the Text

One could simply use any text editor to remove the three following lines:

<<<<<<< HEAD
=======*
*>>>>>>> Conflicting commit

And also compromise between the two versions. Then save the file and stage it using git:

git add auto-assign.yml

Using this method, one might mess the file up and leave some of the aforementioned lines behind. Also, a file with too many conflicts is usually unreadable and very hard to deal with.

Use Git Mergetool

Go ahead and enter the following command into your command line:

git mergetool

If it's your first time, git will probably show you a message like this:

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc codecompare smerge emerge vimdiff
Merging:
.github/workflows/auto-assign.yml

Normal merge conflict for '.github/workflows/auto-assign.yml':
{local}: created file
{remote}: created file
Hit return to start merge resolution tool (bc):

It shows you some of the available merge tools:

  • meld
  • opendiff
  • kdiff3
  • tkdiff
  • xxdiff
  • emerge
  • etc.

As well as the conflict: Both the local and the remote versions have created the same file auto-assign.yml. It also asks you to choose a resolution tool. You can enter one of the tools, or exit (e.g. with Ctrl+C on Linux) and pass the tool from the beginning:

git mergetool --tool=vimdiff3

To see the available merge tools on your machine, run the following command:

git mergetool --tool-help

My machine shows the following tools:

'git mergetool --tool=<tool>' may be set to one of the following:
        araxis           Use Araxis Merge (requires a graphical session)
        opendiff         Use FileMerge (requires a graphical session)
        vimdiff          Use Vim with a custom layout (see `git help mergetool`'s `BACKEND SPECIFIC HINTS` section)
        vimdiff1         Use Vim with a 2 panes layout (LOCAL and REMOTE)
        vimdiff2         Use Vim with a 3 panes layout (LOCAL, MERGED and REMOTE)
        vimdiff3         Use Vim where only the MERGED file is shown

The following tools are valid, but not currently available:
        bc               Use Beyond Compare (requires a graphical session)
        bc3              Use Beyond Compare (requires a graphical session)
        bc4              Use Beyond Compare (requires a graphical session)
        codecompare      Use Code Compare (requires a graphical session)
        deltawalker      Use DeltaWalker (requires a graphical session)
        diffmerge        Use DiffMerge (requires a graphical session)
        diffuse          Use Diffuse (requires a graphical session)
        ecmerge          Use ECMerge (requires a graphical session)
        emerge           Use Emacs' Emerge
        examdiff         Use ExamDiff Pro (requires a graphical session)
        guiffy           Use Guiffy's Diff Tool (requires a graphical session)
        gvimdiff         Use gVim (requires a graphical session) with a custom layout (see `git help mergetool`'s `BACKEND SPECIFIC HINTS` section)
        gvimdiff1        Use gVim (requires a graphical session) with a 2 panes layout (LOCAL and REMOTE)
        gvimdiff2        Use gVim (requires a graphical session) with a 3 panes layout (LOCAL, MERGED and REMOTE)
        gvimdiff3        Use gVim (requires a graphical session) where only the MERGED file is shown
        kdiff3           Use KDiff3 (requires a graphical session)
        meld             Use Meld (requires a graphical session) with optional `auto merge` (see `git help mergetool`'s `CONFIGURATION` section)
        nvimdiff         Use Neovim with a custom layout (see `git help mergetool`'s `BACKEND SPECIFIC HINTS` section)
        nvimdiff1        Use Neovim with a 2 panes layout (LOCAL and REMOTE)
        nvimdiff2        Use Neovim with a 3 panes layout (LOCAL, MERGED and REMOTE)
        nvimdiff3        Use Neovim where only the MERGED file is shown
        p4merge          Use HelixCore P4Merge (requires a graphical session)
        smerge           Use Sublime Merge (requires a graphical session)
        tkdiff           Use TkDiff (requires a graphical session)
        tortoisemerge    Use TortoiseMerge (requires a graphical session)
        winmerge         Use WinMerge (requires a graphical session)
        xxdiff           Use xxdiff (requires a graphical session)

Some of the tools listed above only work in a windowed
environment. If run in a terminal-only session, they will fail.

Some of the tools open a graphical tool, e.g. emerge that opens up an Emacs editor. Some of the tools are terminal-only, e.g. vimdiff which opens a Vim editor in your terminal.

We'll do a comprehensive piece on different merge tools available with git's CLI.

Using an IDE or Editor

Some graphical editors and most of the IDEs come with a git merge tool. The examples would be:

  • JetBrains IDEs, e.g. IntelliJ, WebStorm, PyCharm, etc.
  • Eclipse
  • VSCode

Last Words

I'm used to resolve conflicts manually, even though I'm using sophisticated IDEs. But if you're SSHing into a server, and want to do a merge, you can use the git mergetool command to resolve conflicts in a more visual way.

How do you usually resolve your merge conflicts? Which merge tools do you usually use?

Other Posts in the Series

Post thumbnail
A guide to using Git binary search to find the commit that introduced a bug.
Issue: #16
Series: Git Weekly
Intermediate
Published: 7/27/2022
Post thumbnail
A guide to setting up Git configurations when moving to a new machine.
Issue: #18
Series: Git Weekly
Beginner
Published: 8/22/2022