I am experimenting with ediff-directories, but I am not sure I am using it correctly.

I read in the documentation that, once I supply two directories to ediff-directories, if I press == Emacs compares them recursively.

However, if I press == I only get folders with = signs (meaning that the two folders have identical contents) on the level where I run the command. If I want to see which folders have = signs at deeper levels in the folder hierarchy, I need to re-run the == command at each level.

How can I tell emacs to go recursively all the way to the leaves so that I can see all the differences in the directory difference buffer (accessible via the keyboard command D)?

If anybody knows of a tutorial on how to use ediff-directories (other than the official documentation), I would be highly interested.

Also, if I want to exit a session group (comparison of folders at one level), but I have sessions open for deeper levels, if I press q (quit this session group), Emacs complains with the messaage:

This sesssion group has active sessions---cannot exit

How can I exit session groups without exiting the sub-sessions one by one?


I have used M-x dired-compare-directories, but there is also EdiffTrees, which might serve you better in the situation you describe.


I also needed this feature and came up with the following. The function ediff-directories-recursive works like ediff-directories but recurses into sub-directories.

The magic behind that is temporarily replacing the built-in directory-files by a self-made directory-files-recursive before calling ediff-directories.

 (let ((directory-files-original (symbol-function 'directory-files)))
   `(defun directory-files-recursive (directory &optional full match nosort)
      "Like `directory-files' but recurses into subdirectories. Does not follow symbolic links."
      (let* ((prefix (or (and full "") directory))
    (mapc (lambda (p)
        (let ((fullname (if full p (concat prefix "/" p))))
          (when (and (file-directory-p fullname)
                 (null (or (string-match "\\(^\\|/\\).$" p)
                       (string-match "\\(^\\|/\\)..$" p)
                       (file-symlink-p fullname))))
            (setq dirs (cons p dirs)))))
          (funcall ,directory-files-original directory full nil nosort))
    (setq dirs (nreverse dirs))
    (mapc (lambda (p)
        (when (null (file-directory-p (if full p (concat prefix "/" p))))
          (setq files (cons p files))))
          (funcall ,directory-files-original directory full match nosort))
    (setq files (nreverse files))
    (mapc (lambda (d)
        (setq files
              (append files
                  (if full
                  (apply 'directory-files-recursive (list d full match nosort))
                (mapcar (lambda (n)
                      (concat d "/" n))
                    (apply 'directory-files-recursive (list (concat prefix "/" d) full match nosort)))))))

 `(defun ediff-directories-recursive (dir1 dir2 regexp)
    "Like `ediff-directories' but recurses into sub-directories. Does not follow symbolic links."
    ,(interactive-form (symbol-function 'ediff-directories))
    (let ((directory-files-original (symbol-function 'directory-files)))
        (fset 'directory-files (symbol-function 'directory-files-recursive))
        (ediff-directories dir1 dir2 regexp)
        (fset 'directory-files directory-files-original))))))
  • I did eval-buffer and got this: Debugger entered--Lisp error: (wrong-type-argument symbolp (autoload "ediff" 890739 t nil)) interactive-form((autoload "ediff" 890739 t nil)) Any suggestion? – nephewtom Aug 25 '15 at 10:09

There is ztree package available from Melpa which supports recursive directory tree comparison: M-x ztree-diff using GNU diff utilities to compare corresponding files.

If you use use-package then to install and configure ztree package, add to your .emacs:

;; ** recursive directory tree comparison: M-x ztree-diff
(use-package ztree
  :ensure t) ; needs GNU diff utility

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.