How to determine if Git merge is in process

You can safely check for the existence of MERGE_HEAD in your git directory[1] to determine whether there's a merge in progress. The MERGE_HEAD file contains the commit ids that are being merged in, that will be the nth parents of the committed merge. For example, if I try to merge branch br1 which is at c085e0c:

> git merge --no-ff --no-commit br1
Automatic merge went well; stopping before committing as requested

> cat .git/MERGE_HEAD
c085e0caa2598064bfde9cc6318bd2c73fee2371

If you are doing an octopus merge, then you will see more than one commit id in this file (newline separated):

> git merge --no-ff --no-commit br2 br3
Fast-forwarding to: br2
Trying simple merge with br3
Automatic merge went well; stopping before committing as requested

> cat .git/MERGE_HEAD
69b0169b1cba60de86161b375f013c59ad9581d8
99dad0187351d61ae8e88d49c96d7383f9e8fa6d

Using MERGE_HEAD is actually how git clients determine whether there's a merge in progress. Some provide this insight through leaky abstractions:

> git merge --abort
fatal: There is no merge to abort (MERGE_HEAD missing).

So checking for the presence of MERGE_HEAD is perfectly acceptable and is is as future proof as anything in software - meaning that any changes to git-merge would have to take compatibility with other git clients into account and would (hopefully!) gracefully transition and/or provide backward compatibility.

[1] You can trust the existence of MERGE_HEAD much more than you can trust that .git is underneath your working directory. Somebody could use the --git-dir flag or the GIT_DIR environment variable.


One trick is to use a Git command that will fail if a merge is in progress. You can then check the return code of the command. You'll also want to make sure that the command will not affect your working copy or index in the event that it succeeds. While there are many commands that fall into this category, one that seems appropriate is

git merge HEAD

which returns a 128 code if a merge is in progress, but 0 otherwise. Note that when a merge is not in-process, this command will simply print Already up-to-date since you are just merging with yourself. So, for scripting purposes, you can do this (in BASH)

git merge HEAD &> /dev/null
result=$?
if [ $result -ne 0 ]
then
    echo "Merge in progress."
else
    echo "Merge not in progress."
fi

Note that even with the --quiet flag of git merge, an in-process merge will still cause this command to print to the error stream. This is why I redirect its output to /dev/null.

Tags:

Git

Git Merge