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

From: Tassilo Horn <[email-masked]>
Date: Sun, 19 Jan 2025 11:33:24 +0100

Michael Heerdegen <[email-masked]> writes:

Hi Michael,

> The question than would be if we want to reimplement the command, or
> if we try to make it (more) robust.
>
> We could, for example, remember the current position as a marker
> instead of a number,

Oh, just remembering point as a numeric value is certainly wrong given
that (un)compressing will certainly change the length of filenames.  But
sorting order is also a problem where even a marker won't help.  For
example, with just 21 files named 0 to 20 the initial sorting order is:

--8<---------------cut here---------------start------------->8---
❯ ls -l                                                                                 
total 84
-rw-r--r-- 1 horn horn  70 19. Jan 11:11 0
-rw-r--r-- 1 horn horn  69 19. Jan 11:11 1
-rw-r--r-- 1 horn horn  65 19. Jan 11:11 10
-rw-r--r-- 1 horn horn  26 19. Jan 11:11 11
-rw-r--r-- 1 horn horn  60 19. Jan 11:11 12
-rw-r--r-- 1 horn horn  43 19. Jan 11:11 13
-rw-r--r-- 1 horn horn  79 19. Jan 11:11 14
-rw-r--r-- 1 horn horn  72 19. Jan 11:11 15
-rw-r--r-- 1 horn horn  40 19. Jan 11:11 16
-rw-r--r-- 1 horn horn  91 19. Jan 11:11 17
-rw-r--r-- 1 horn horn  37 19. Jan 11:11 18
-rw-r--r-- 1 horn horn  65 19. Jan 11:11 19
-rw-r--r-- 1 horn horn 104 19. Jan 11:11 2
-rw-r--r-- 1 horn horn  44 19. Jan 11:11 20
-rw-r--r-- 1 horn horn  46 19. Jan 11:11 3
-rw-r--r-- 1 horn horn  82 19. Jan 11:11 4
-rw-r--r-- 1 horn horn  66 19. Jan 11:11 5
-rw-r--r-- 1 horn horn  67 19. Jan 11:11 6
-rw-r--r-- 1 horn horn  82 19. Jan 11:11 7
-rw-r--r-- 1 horn horn  70 19. Jan 11:11 8
-rw-r--r-- 1 horn horn  68 19. Jan 11:11 9
--8<---------------cut here---------------end--------------->8---

After compressing the first 5 files 0, 1, 10, 11, and 12 it becomes:

--8<---------------cut here---------------start------------->8---
~/tmp/test 
❯ ls -l                                                                                 
total 84
-rw-r--r-- 1 horn horn  92 19. Jan 11:11 0.gz
-rw-r--r-- 1 horn horn  88 19. Jan 11:11 10.gz
-rw-r--r-- 1 horn horn  49 19. Jan 11:11 11.gz
-rw-r--r-- 1 horn horn  83 19. Jan 11:11 12.gz
-rw-r--r-- 1 horn horn  43 19. Jan 11:11 13
-rw-r--r-- 1 horn horn  79 19. Jan 11:11 14
-rw-r--r-- 1 horn horn  72 19. Jan 11:11 15
-rw-r--r-- 1 horn horn  40 19. Jan 11:11 16
-rw-r--r-- 1 horn horn  91 19. Jan 11:11 17
-rw-r--r-- 1 horn horn  37 19. Jan 11:11 18
-rw-r--r-- 1 horn horn  65 19. Jan 11:11 19
-rw-r--r-- 1 horn horn  91 19. Jan 11:11 1.gz
-rw-r--r-- 1 horn horn 104 19. Jan 11:11 2
-rw-r--r-- 1 horn horn  44 19. Jan 11:11 20
-rw-r--r-- 1 horn horn  46 19. Jan 11:11 3
-rw-r--r-- 1 horn horn  82 19. Jan 11:11 4
-rw-r--r-- 1 horn horn  66 19. Jan 11:11 5
-rw-r--r-- 1 horn horn  67 19. Jan 11:11 6
-rw-r--r-- 1 horn horn  82 19. Jan 11:11 7
-rw-r--r-- 1 horn horn  70 19. Jan 11:11 8
-rw-r--r-- 1 horn horn  68 19. Jan 11:11 9
--8<---------------cut here---------------end--------------->8---

So here the 1.gz will be uncompressed again if auto-revert-mode decided
to revert in that moment.  Just ramp up the number of files to 1000 and
you'll surely get a (un)compression infloop in dired.

> and/or try to prevent auto revert while the command is processed.

That seems to be advisable as a first aid.  Not sure if there are other
ways to trigger the issue, too.

> AFAIU, `dired-buffer-stale-p' could be changed to return nil in this
> case to prevent reverting.

Good idea.  I've tried this simple patch and it fixes the issue for me.

--8<---------------cut here---------------start------------->8---
diff --git a/lisp/dired.el b/lisp/dired.el
index bab5e833a76..1152d85f149 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1289,6 +1289,10 @@ 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 set and we must not
+         ;; auto-revert.
+         (null inhibit-read-only)
         (dired-directory-changed-p dirname))))
 
 (defcustom dired-auto-revert-buffer nil
--8<---------------cut here---------------end--------------->8---

Probably testing inhibit-read-only is not TRT but the expansion of
dired-map-over-marks should explicitly let-bind some new
dired--map-over-marks-in-progress variable to make it more explicit...

> Or would binding dired-auto-revert-buffer -> nil already be enough?

No.  That's only for reverting on re-visiting a dired buffer and has no
influence on auto-revert-mode.

Bye,
Tassilo