I use the following script as mergetool which works quite well.
#!/bin/bash
# test args
if [ ! ${#} -ge 3 ]; then
echo 1>&2 "Usage: ${0} LOCAL REMOTE MERGED BASE"
echo 1>&2 " (LOCAL, REMOTE, MERGED, BASE can be provided by \`git mergetool'.)"
exit 1
fi
# tools
_EMACSCLIENT=/usr/local/bin/emacsclient
_BASENAME=/bin/basename
_CP=/bin/cp
_EGREP=/bin/egrep
_MKTEMP=/bin/mktemp
# args
_LOCAL=${1}
_REMOTE=${2}
_MERGED=${3}
if [ -r ${4} ] ; then
_BASE=${4}
_EDIFF=ediff-merge-files-with-ancestor
_EVAL="${_EDIFF} \"${_LOCAL}\" \"${_REMOTE}\" \"${_BASE}\" nil \"${_MERGED}\""
else
_EDIFF=ediff-merge-files
_EVAL="${_EDIFF} \"${_LOCAL}\" \"${_REMOTE}\" nil \"${_MERGED}\""
fi
# console vs. X
if [ "${TERM}" = "linux" ]; then
unset DISPLAY
_EMACSCLIENTOPTS="-t"
else
_EMACSCLIENTOPTS="-c"
fi
# run emacsclient
${_EMACSCLIENT} ${_EMACSCLIENTOPTS} -a "" -e "(${_EVAL})" 2>&1
# check modified file
if [ ! $(egrep -c '^(<<<<<<<|=======|>>>>>>>|####### Ancestor)' ${_MERGED}) = 0 ]; then
_MERGEDSAVE=$(${_MKTEMP} --tmpdir `${_BASENAME} ${_MERGED}`.XXXXXXXXXX)
${_CP} ${_MERGED} ${_MERGEDSAVE}
echo 1>&2 "Oops! Conflict markers detected in $_MERGED."
echo 1>&2 "Saved your changes to ${_MERGEDSAVE}"
echo 1>&2 "Exiting with code 1."
exit 1
fi
exit 0
To use it with `git mergetool' put the following in your git config:
[merge]
tool = ediff
[mergetool "ediff"]
cmd = /path/to/ediff-merge-script $LOCAL $REMOTE $MERGED $BASE
trustExitCode = true
Additionally, you should check (in the script) the paths of the tools used and if the poor man's console detection works for you.
The script itself starts an emacs client (or emacs followed by an emacs client, -a ""
) and evals either ediff-merge-files-with-ancestor
or ediff-merge-files
if there's no base version (e.g. when merging two branches where the same path/file has been created independently).
After the emacs client has finished the merged file is checked for conflict markers. Should those be found, your work will be saved away to a temporary file, the script will exit with code 1 and git will restore the pre-mergetool contents of the merged file.
When there are no conflict markers present, the script exits with code 0 and git will regard the merge as successful.
Important: Setting the mergetool option trustExitCode
to true
as well as the post-edit check for conflict markers will not work if you start emacsclient
with the --no-wait
option.