Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question
What I'd pay for ediff to become as usable as Beyond Compare... –  ckhan Sep 4 '12 at 17:26

2 Answers 2

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))))))
share|improve this answer

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

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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