Dear Maintainer,
With the Tramp shipped in Emacs 30.1 (Tramp 2.7.1.30.1), files opened via
gvfs-based methods (davs, dav, smb, afp, sftp via gvfs, etc.) are never
detected as changed on the remote side when the gvfs share was already
mounted. Emacs therefore neither offers the "changed on disk; really edit
the buffer?" prompt on first edit nor the "has changed since visited or
saved" prompt on save, and silently overwrites the remote modifications.
I lost data this way before noticing.
Cause:
In tramp-gvfs.el, `tramp-gvfs-maybe-open-connection' sets the "connected"
connection property only inside the
`(unless (tramp-gvfs-connection-mounted-p vec) ...)' branch. When the
location is already mounted (e.g. by Nautilus, `gio mount', or a previous
Emacs session), the property is never set. Consequently
`(file-remote-p FILE nil 'connected)' returns nil, and
`tramp-handle-verify-visited-file-modtime' takes its early exit and
always returns t without contacting the server.
Steps to reproduce:
1. gio mount davs://USER@HOST/share (or have it mounted already)
2. emacs -Q /davs:USER@HOST:/share/file.txt
3. Modify file.txt on the server.
4. Edit the buffer in Emacs: no supersession prompt.
C-x C-s: the remote change is overwritten without warning.
M-: (file-remote-p buffer-file-name nil 'connected) => nil
M-: (verify-visited-file-modtime) => t (instantly)
I verified this with `emacs -Q --batch' while the share was already
mounted. The test script visits the file with `find-file-noselect',
rewrites it on the server with `gio save', and then calls
`verify-visited-file-modtime' in the visiting buffer:
without workaround: connected=nil verify-visited-file-modtime=t (0.00s)
with workaround: connected=t verify-visited-file-modtime=nil (2.68s)
Fix:
This is fixed upstream. Tramp is developed in its own repository
(tramp.git on Savannah) and periodically synced into Emacs:
- Tramp: commit 28d86500e50da9da64bba6da76e87a12f7e4a3c5 on
branch-2-7-stable (2025-06-05), "Set "connected" property in time."
It is first released in Tramp 2.7.3 (GNU ELPA, 2025-06-29).
https://git.savannah.gnu.org/cgit/tramp.git/commit/?id=28d86500e50da9da64bba6da76e87a12f7e4a3c5
- Emacs: commit 4a3b6daf76c385fc58759d57aeb4d34e8acc31e5 on the
emacs-30 branch (2025-08-16), "Sync with Tramp 2.7.4-pre", which
brings the fix into Emacs. It is not yet in any Emacs release.
https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=4a3b6daf76c385fc58759d57aeb4d34e8acc31e5
Emacs 30.2 bundles a Tramp labeled 2.7.3.30.2, but that copy still has
the bug. It is a pre-release Tramp 2.7.3 snapshot that was frozen for
the Emacs 30.2 release on 2025-05-18, before the fix landed. The
standalone Tramp 2.7.3 release with the fix came later.
The fix moves the property assignment out of the `unless' so that it
always runs. This is the relevant hunk from the Emacs commit:
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -2345,11 +2345,11 @@ connection if a previous connection has died for some reason."
;; Save the password.
(ignore-errors
(and (functionp tramp-password-save-function)
- (funcall tramp-password-save-function)))
+ (funcall tramp-password-save-function))))))
- ;; Mark it as connected.
- (tramp-set-connection-property
- (tramp-get-connection-process vec) "connected" t))))))
+ ;; Mark it as connected.
+ (tramp-set-connection-property
+ (tramp-get-connection-process vec) "connected" t)))
(defun tramp-gvfs-gio-tool-p (vec)
"Check, whether the gio tool is available."
(Line numbers are from the emacs-30 branch; in 30.1 the hunk is at
around line 2321.)
The same commit makes the equivalent change in tramp-rclone.el for the
rclone method. I have not tested rclone.
Since this causes silent loss of user data and the fix is small and
self-contained, please consider it for a trixie stable update.
Workaround for affected users, in ~/.emacs:
(with-eval-after-load 'tramp-gvfs
(advice-add 'tramp-gvfs-maybe-open-connection :after
(lambda (vec)
(tramp-set-connection-property
(tramp-get-connection-process vec) "connected" t))))
Additional versions: gvfs 1.57.2-2+deb13u1, gvfs-backends 1.57.2-2+deb13u1.