[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

How to use emacs as a "diff3 -m" compatible merge tool?

From: Tassilo Horn
Subject: How to use emacs as a "diff3 -m" compatible merge tool?
Date: Thu, 09 Jun 2022 12:52:20 +0200
User-agent: mu4e 1.7.26; emacs 29.0.50

Hi all,

there are certain tools/scripts such as Arch GNU/Linux' pacdiff which
call a user-defined tool for doing a 3-way merge.  For example, pacdiff
wants to merge the current config file with the current package-provided
config file and the package-provided config file of a previous version
as a base/ancestor.

pacdiff calls the user-defined mergeprog like so:

--8<---------------cut here---------------start------------->8---
        if $mergeprog "$file" "$base" "$pacfile" >"$merged"; then
                msg2 "Merged without conflicts."
--8<---------------cut here---------------end--------------->8---

I'd like to use emacs as mergetool so need to support these calling
convention (which are the ones of "diff3 -m"), i.e.,

  2. a successful merge exits zero, an aborted merge exits non-zero
  3. the merge result is printed to stdout

I've come up with two versions (ediff-merge & emerge):

--8<---------------cut here---------------start------------->8---
(defun th/command-line-ediff-merge3 (_switch)
  "Do a 3-way merge using `ediff-merge-files-with-ancestor'."
  (let ((make-backup-files nil)
        (my-version    (pop command-line-args-left))
        (base-version  (pop command-line-args-left))
        (their-version (pop command-line-args-left)))
     my-version their-version base-version)))

(add-to-list 'command-switch-alist
             '("--ediff-merge3" . th/command-line-ediff-merge3))

(defun th/command-line-emerge3 (_switch)
  "Do a 3-way merge using `emerge-files-with-ancestor'."
  (let* ((make-backup-files nil)
         (my-version    (pop command-line-args-left))
         (base-version  (pop command-line-args-left))
         (their-version (pop command-line-args-left))
         (merged (make-temp-file (concat (file-name-nondirectory my-version)
     nil my-version their-version base-version merged)))

(add-to-list 'command-switch-alist
             '("--emerge3" . th/command-line-emerge3))
--8<---------------cut here---------------end--------------->8---

So now I can call "emacs --ediff-merge3 my base theirs" or "emacs
--emerge3 my base theirs" and do the merge.  However, points 2 and 3
are not yet addressed.

So how to address those?  I guess I need to stick a function in
ediff-quit-merge-hook and emerge-quit-hook.  But then?  How do I print
the merge buffer's contents to stdout?  And how can I influence the exit
code? (I could do (kill-emacs my-exit-code) but would be more happy if I
could also use the merge command with emacsclient where I obviously
don't want to kill emacs.)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]