Based on @Drew's answer, with progress reporting since it can be slow with many files open.
(interactive) (let* ( ;; pairs of (filename, buf) (filename-and-buffer-list (mapcar (lambda (buf) (list (buffer-file-name buf) buf)) (seq-filter 'buffer-file-name (buffer-list)))) (count (length filename-and-buffer-list)) (count-final 0) (count-close 0) (count-error 0) ;; Keep text at a fixed width when redrawing. (format-count (format "%%%dd" (length (number-to-string count)))) (format-text (concat "Reverting [" format-count " of " format-count "] %3d%%: %s")) (index 1)) (message "Begin reverting %d buffers..." count) (while filename-and-buffer-list (cl-destructuring-bind (filename buf) (pop filename-and-buffer-list) ;; Revert only buffers containing files, which are not modified; ;; do not try to revert non-file buffers like *Messages*. (message format-text index count (round (* 100 (/ (float index) count))) filename) (if (file-exists-p filename) ;; If the file exists, revert the buffer. (if (with-demoted-errors "Error: %S" (with-current-buffer buf (revert-buffer :ignore-auto :noconfirm)) t) (setq count-final (1+ count-final)) (setq count-error (1+ count-error))) ;; If the file doesn't exist, kill the buffer. (let (kill-buffer-query-functions) ; No query done when killing buffer. (message "Closing non-existing file buffer: %s" buf) (kill-buffer buf) (setq count-close (1+ count-close)))) (setq index (1+ index)))) (message (concat "Finished Revert All: " (format "%d buffer(s)" count-final) (if (zerop count-close) "" (format ", %d closed" count-close)) (if (zerop count-error) "" (format ", %d error (see message buffer)" count-error))))))