Subject: bug#54016: 29.0.50; TRAMP + sshfs says constantly that file changed

From: Michael Albinus <[email-masked]>
Date: Wed, 16 Feb 2022 16:26:08 +0100

Ergus <[email-masked]> writes:

Hi,

>>> Using tramp+sshfs it works pretty much fine at the beginning but after
>>> some minutes it interrupts constantly saying that the file changed on
>>> disk and asks for edit confirmation.
>>>
>>> By constantly I mean every time a new edit is attempt I get this (even
>>> several times consecutive).
>>>
>>> ```
>>> Saving file /sshfs:XXX:XXXX
>>> benchmarks_ompss.h has changed since visited or saved.  Save anyway? (y or n) y
>>> benchmarks_ompss.h changed on disk; really edit the buffer? (y, n, r or C-h) y
>>> File on disk now will become a backup file if you save these changes.
>>> Wrote /sshfs:XXX:XXXX
>>> ```
>>
>>Well, I would need a recipe to reproduce. Could you run it, when
>>tramp-verbose is set to 10? And please tell me at which time the problem
>>starts to appear, so I have a chance to find it in the debug buffer.
>>
>>I know that the debug buffer will be huge after a while, but there is no
>>problem if you send it directly to me (or a URL where I could find it).
>>
>
> 1) C-x C-f /sshfs:mn3:/home/ergus/cholesky_ompss2/cholesky_utils.c
> 2) edit and save (C-x C-f)
>
> 3) Try to edit again:
>
> and get the message:
>
> ```
> cholesky_utils.c changed on disk; really edit the buffer? (y, n, r or C-h) y
> File on disk now will become a backup file if you save these changes.
> ```
>
> While this is printed in the debug buffer.

Thanks for the recipe and the traces. Finally, I could reproduce the
problem locally, it was due to a missing update of the buffer's
modification time. The appended patch fixes this for me, could you pls
test?

Best regards, Michael.

diff --git a/lisp/tramp-sshfs.el b/lisp/tramp-sshfs.el
index ca682466..710b55b1 100644
--- a/lisp/tramp-sshfs.el
+++ b/lisp/tramp-sshfs.el
@@ -107,9 +107,9 @@
     (file-name-nondirectory . tramp-handle-file-name-nondirectory)
     ;; `file-name-sans-versions' performed by default handler.
     (file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
-    (file-notify-add-watch . ignore)
-    (file-notify-rm-watch . ignore)
-    (file-notify-valid-p . ignore)
+    (file-notify-add-watch . tramp-handle-file-notify-add-watch)
+    (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
+    (file-notify-valid-p . tramp-handle-file-notify-valid-p)
     (file-ownership-preserved-p . ignore)
     (file-readable-p . tramp-handle-file-readable-p)
     (file-regular-p . tramp-handle-file-regular-p)
@@ -389,6 +389,13 @@ arguments to pass to the OPERATION."
 	 start end (tramp-fuse-local-file-name filename) append 'nomessage)
 	(tramp-flush-file-properties v localname))

+      ;; Set file modification time.
+      (when (or (eq visit t) (stringp visit))
+	(set-visited-file-modtime
+	 (or (file-attribute-modification-time
+	      (file-attributes filename))
+	     (current-time))))
+
       ;; Unlock file.
       (when file-locked
 	;; `unlock-file' exists since Emacs 28.1.