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?