I'd like to invoke emacs' ediff-merge-files function for merging files with the unison file synchronizer. To avoid starting a new instance, I prefer using emacsclient:

emacsclient --eval '(ediff-merge-files "CURRENT1" "CURRENT2" nil "NEW")'

However, emacsclient returns instantly (as it would do when given plain files and the --no-wait option). Of course, unison then complains that no files have been edited.

Is there a way to let emacsclient wait until I'm finished with the merge?


I see 2 ways to do this.

wrap your call to ediff-merge-files around another emacs function that will wait for the call to finish, can play around with doing some hacks into the startup hooks, but this could get very messy

wrap your call to emacsclient with a script that waits for the new file to be created before returning, if the temporary file is created on demand then this is an easier solution, if the new file may already exist, then you'll need to use a placeholder file

Example script - ediff-wait, it's hacked up and has minimal sanity checks


[ -f $3 ] && exit 1  # merge file exists?

emacsclient --eval "( ediff-merge-files \"$1\" \"$2\" nil \"$3\" )"
while /bin/true; do
  [ -f $3 ] && exit 0
  sleep 1

Emacsclient will wait if you ask it to create a new frame. Hence, use either:

emacsclient -c --eval '(ediff-merge-files "CURRENT1" "CURRENT2" nil "NEW")' if you want to create a graphical frame or

emacsclient -t --eval '(ediff-merge-files "CURRENT1" "CURRENT2" nil "NEW")' if you want a terminal frame.


It seems that the problem with using emacsclient as a diff tool is that it always returns 0 as status code making it impossible for git to decide if the merge succeeded or not.

A solution was proposed on the Mercurial wiki:


if [ $# -lt 1 ]; then
  echo 1>&2 "Usage: $0 local other base output"
  exit 1


OUTPUT=`emacsclient --no-wait --eval "(ediff-merge-with-ancestor \"$local\" \"$other\" \"$base\" nil \"$output\")" 2>&1`
echo $OUTPUT | grep -v "Ediff Control Panel"

if echo "$OUTPUT" | grep -q '^*ERROR*'; then
    exit 1

Put this in a shell script in your path and things should be dandy.

[NOTE: This issue has been fixed in the emacs trunk.]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.