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 n
th 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
.