Needed to diff two directories, but only interested in file size changes. diff, find, sort, and stat seem to do the job:
diff <(find dir1 -type f -exec stat -f '%N %z' '{}' \; | sort) <(find dir2 -type f -exec stat -f '%N %z' '{}' \; | sort)
1,3c1,2
< dir1/one.txt 14
< dir1/subdir/file.txt 5
< dir1/three.txt 7
---
> dir2/one.txt 19
> dir2/two.txt 0
Note: Using diff, find, sort, and stat on macOS.
I've since learned about mtree (thanks Roman!). A nice utility to add to the toolbox.
mtree -p emacs-25.1 -c -k size -d
# user: me
# machine: my-machine
# tree: /path/to/emacs-25.1
# date: Wed Dec 5 22:21:07 2018
# .
/set type=dir
. size=1152
# ./admin
admin size=960
# ./admin/charsets
charsets size=544
# ./admin/charsets/glibc
glibc size=3392
# ./admin/charsets/glibc
..
# ./admin/charsets/mapfiles
mapfiles size=640
# ./admin/charsets/mapfiles
..
I've added Emacs ediff to the mix:
(require 'f)
(defun ar/ediff-dir-content-size ()
"Diff all subdirectories (sizes only) in two directories."
(interactive)
(let* ((dir1-path (read-directory-name "Dir 1: "))
(dir2-path (read-directory-name "Dir 2: "))
(buf1 (get-buffer-create (format "*Dir 1 (%s)*" (f-base dir1-path))))
(buf2 (get-buffer-create (format "*Dir 2 (%s)*" (f-base dir2-path)))))
(with-current-buffer buf1
(erase-buffer))
(with-current-buffer buf2
(erase-buffer))
(shell-command (format "cd %s; find . -type d | sort | du -h" dir1-path) buf1)
(shell-command (format "cd %s; find . -type d | sort | du -h" dir2-path) buf2)
(ediff-buffers buf1 buf2)))