Table Of Content
Skip to the relevant sections if needed.
- 2-min tutorial to do it the quick-and-dirty-way
- Concepts for resolving
- Setting up different editors / tool for using
mergetoolsimple code example for
- Other great references and tutorials
Concepts for resolving
git, we need to understand the following terminology to understand what is being merged:
headfor the file(s) from the current branch on the machine that you are using.
headfor files(s) from a remote location that you are trying to merge into your
BASE- the common ancestor(s) of
MERGED- the tag /
HEADobject after the merge - this is saved as a new commit.
mergetool from editors will display both
REMOTE so you can decide which changes to keep.
Please read this tutorial explaining the HEAD objects if you do not know what it is. It will help your understanding of Git tremendously.
Setting up different editors / tool for using
We have to change the
git config to set a default mergetool.
In this example, we will use
$ git config merge.tool vimdiff
We can also set the editor to display the common ancestor
BASE while we examine what changes are in
REMOTE with the following setting:
$ git config merge.conflictstyle diff3
Finding out what
mergetool editors are supported
$ git mergetool --tool-help
And we list a few of them:
gvimdiff- almost identical to
vimdiffbut uses the Linux GUI for
Vim, please refer to
vimdiffif you still use the keyboard commands for
Or consult the community of your favorite editor to see how to do the equivalent operations for your editor.
Do not prompt before launching the merge resolution tool
$ git config mergetool.prompt false
mergetool simple code example
creating the git repo
$ mkdir galaxyZoo $ cd galaxyZoo $ git init $ vim astrophy_obj.txt
Add some galaxy types into
astrophy_obj.txt then save the file.
# content of astrophy_obj.txt spiral elliptical bar irregular
save then commit the file.
$ git add astrophy_obj.txt $ git commit -m 'Initial commit' $ git branch astrophy_objects # create a new branch $ git checkout astrophy_objects # change to new branch $ vim astrophy_obj.txt # make changes to file
barred in the file.
$ git commit -am 'changed bar to barred' $ git checkout master # change back to master branch $ vim astrophy_obj.txt # add the word `galaxy` to the end of each line using Vim REGEX # type `:%s/$/ galaxy/g` in Vim then press enter and save `:wq` $ git commit -am 'added galaxy to each line' # merge from the astrophy_objects branch to current branch, i.e. master $ git merge astrophy_objects
Then you will see some error messages:
Auto-merging astrophy_obj.txt CONFLICT (content): Merge conflict in astrophy_obj.txt Automatic merge failed; fix conflicts and then commit the result.
We can bring up the
$ git mergetool
Then it will bring up the different versions of the file in different
Vim splits panels.
+--------------------------------+ | LOCAL | BASE | REMOTE | +--------------------------------+ | MERGED | +--------------------------------+
The top left split panel is the
LOCAL, top middle split is
BASE and top right split is
The bottom split refers to the
You can find this info in the bottom bar of each split (I have put 3 yellow rectangles to highlight that info).
Now if your terminal has any GUI capability and you have compiled
Vim correctly with GUI support, you can use your mouse to click on the bottom split to edit it.
Or if you are a
Vim ninja, you can use the keyboard shortcut to move to different splits.
Ctrl w + h # move to the split on the left Ctrl w + j # move to the split below Ctrl w + k # move to the split on top Ctrl w + l # move to the split on the right
You can either incorporate the changes by manually editing the
Vim shortcuts pull from one of the
:diffg RE # get from REMOTE :diffg BA # get from BASE :diffg LO # get from LOCAL
save the changes then quit with
:wqa to close all the splits.
Remember to commit the merge.
$ git commit -am 'merged from several branches'
Resolving conflict from a
If you were trying to do a
git pull when you ran into
follow all steps in the previous section for using the
mergetool, then do:
$ git rebase –continue
This command will
Forward-port local commits to the updated upstream HEAD.
according to the documentation, meaning your local commits will be pushed to the
upstream remote branch
as a new forward commit that doesn't interfere with previous commits.
Hooray now you can claim that you can collaborate with others with Git without messing up with your collaborators' commits.
vimdiff keyboard shortcuts
]c - Jump to the next change. [c - Jump to the previous change.
Other great references and tutorials
- Git mergetool documentation on git-scm.com
- Must-read tutorial: the concepts of branching and merging from Charles Duan
- Improving Vimdiff as a Git mergetool
Thanks to @ekalosak's comment, I have fixed a mistake confusing the difference branches.