Subject: bug#75626: 31.0.50; Dired misses or double-processes files when auto-revert-mode is enabled

From: Tassilo Horn <[email-masked]>
Date: Mon, 20 Jan 2025 16:31:52 +0100

Tassilo Horn <[email-masked]> writes:

Hi again,

>> Then, finally, I would name it `dired--prevent-auto-revert' because
>> this might be useful in other places as well.
>
> Sounds good.  I'll make that change, maybe later or tomorrow.

Here it is for a final review.

I took the liberty to name the new variable
dired--inhibit-auto-revert-mode because "inhibit" is well-established in
the Emacs code-base ("prevent" is only used once) and I wanted to have
auto-revert-mode in the name to make it clearer that it has nothing to
do with dired-auto-revert-buffer.

--8<---------------cut here---------------start------------->8---
>From 1c90086e90967303db0409a828e4514fc5235305 Mon Sep 17 00:00:00 2001
From: Tassilo Horn <[email-masked]>
Subject: [PATCH] Don't skip or double-process files in dired with
 auto-revert-mode (bug#75626)

* lisp/dired.el (dired--inhibit-auto-revert-mode): New variable.
(dired-map-over-marks): Make the generated code bind it.
(dired-buffer-stale-p): Return nil if dired--inhibit-auto-revert-mode is
non-nil.
---
 lisp/dired.el | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/lisp/dired.el b/lisp/dired.el
index 2087a6f6f21..47f6fd7c4ce 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -944,6 +944,9 @@ dired-mark-if
                           ""))))
     (and (> count 0) count)))
 
+(defvar-local dired--inhibit-auto-revert-mode nil
+  "A non-nil value prevents `auto-revert-mode' from reverting the buffer.")
+
 (defmacro dired-map-over-marks (body arg &optional show-progress
 				     distinguish-one-marked)
   "Eval BODY with point on each marked line.  Return a list of BODY's results.
@@ -980,7 +983,9 @@ dired-map-over-marks
   ;;endless loop.
   ;;This warning should not apply any longer, sk  2-Sep-1991 14:10.
   `(prog1
-       (let ((inhibit-read-only t) case-fold-search found results)
+       (let ((dired--inhibit-auto-revert-mode t)
+             (inhibit-read-only t)
+             case-fold-search found results)
 	 (if (and ,arg (not (eq ,arg 'marked)))
 	     (if (integerp ,arg)
 		 (progn	;; no save-excursion, want to move point.
@@ -1289,6 +1294,12 @@ dired-buffer-stale-p
 	 ;; Do not auto-revert when the dired buffer can be currently
 	 ;; written by the user as in `wdired-mode'.
 	 buffer-read-only
+         ;; When a dired operation using dired-map-over-marks is in
+         ;; progress, inhibit-read-only is bound to some non-nil value
+         ;; and we must not auto-revert because that could change the
+         ;; order of files leading to skipping or double-processing (see
+         ;; bug#75626).
+         (not dired--inhibit-auto-revert-mode)
 	 (dired-directory-changed-p dirname))))
 
 (defcustom dired-auto-revert-buffer nil
-- 
2.48.1
--8<---------------cut here---------------end--------------->8---

Bye,
Tassilo