emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 895562a8b2: Implement file modification check in Tramp


From: Michael Albinus
Subject: master 895562a8b2: Implement file modification check in Tramp
Date: Thu, 3 Feb 2022 08:21:33 -0500 (EST)

branch: master
commit 895562a8b24fc637fb422d38ea64e7d445b3480d
Author: Michael Albinus <michael.albinus@gmx.de>
Commit: Michael Albinus <michael.albinus@gmx.de>

    Implement file modification check in Tramp
    
    * lisp/net/tramp.el (tramp-handle-lock-file): Check, whether FILE
    is modified.
    
    * test/lisp/net/tramp-tests.el (tramp-test39-detect-external-change):
    New test.
---
 lisp/net/tramp.el            |  8 +++++
 test/lisp/net/tramp-tests.el | 72 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)

diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index c6e55ff688..121ede42c4 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -4008,6 +4008,14 @@ Do not set it manually, it is used buffer-local in 
`tramp-get-lock-pid'.")
   ;; was visited.
   (catch 'dont-lock
     (unless (eq (file-locked-p file) t) ;; Locked by me.
+      (when (and buffer-file-truename
+                (not (verify-visited-file-modtime))
+                (file-exists-p file))
+       ;; In filelock.c, `userlock--ask-user-about-supersession-threat'
+       ;; is called, which also checks file contents.  This is unwise
+       ;; for remote files.
+       (ask-user-about-supersession-threat file))
+
       (when-let ((info (tramp-get-lock-file file))
                 (match (string-match tramp-lock-file-info-regexp info)))
        (unless (ask-user-about-lock
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 01fe7355f4..b41824a6cf 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -6018,6 +6018,78 @@ Use direct async.")
        (ignore-errors (delete-file tmp-name1))
        (tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)))))
 
+;; The function was introduced in Emacs 28.1.
+(ert-deftest tramp-test39-detect-external-change ()
+  "Check that an external file modification is reported."
+  (skip-unless (tramp--test-enabled))
+  (skip-unless (not (tramp--test-ange-ftp-p)))
+  ;; Since Emacs 28.1.
+  (skip-unless (fboundp 'file-locked-p))
+
+  (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
+    (dolist (create-lockfiles '(nil t))
+      (let ((tmp-name (tramp--test-make-temp-name nil quoted))
+           (remote-file-name-inhibit-cache t)
+           (remote-file-name-inhibit-locks nil)
+           tramp-allow-unsafe-temporary-files
+            (inhibit-message t)
+           ;; tramp-rclone.el and tramp-sshfs.el cache the mounted files.
+           (tramp-fuse-unmount-on-cleanup t)
+            auto-save-default
+           (backup-inhibited t)
+           noninteractive)
+        (with-temp-buffer
+          (unwind-protect
+             (progn
+               (setq buffer-file-name tmp-name
+                     buffer-file-truename tmp-name)
+               (insert "foo")
+               ;; Bug#53207: with `create-lockfiles' nil, saving the
+               ;; buffer results in a prompt.
+               (cl-letf (((symbol-function 'yes-or-no-p)
+                          (lambda (_) (ert-fail "Test failed unexpectedly"))))
+                 (save-buffer))
+               (should-not (file-locked-p tmp-name))
+
+               ;; For local files, just changing the file
+               ;; modification on disk doesn't hurt, because file
+               ;; contents in buffer and on disk are equal.  For
+               ;; remote files, file contents is not compared.  We
+               ;; mock an older modification time in buffer, because
+               ;; Tramp regards modification times equal if they
+               ;; differ for less than 2 seconds.
+               (set-visited-file-modtime (time-add (current-time) -60))
+               ;; Some Tramp methods cannot check the file
+               ;; modification time properly, for them it doesn't
+               ;; make sense to test.
+               (when (not (verify-visited-file-modtime))
+                 (cl-letf (((symbol-function 'read-char-choice)
+                            (lambda (prompt &rest _) (message "%s" prompt) 
?y)))
+                   (ert-with-message-capture captured-messages
+                     (insert "bar")
+                     (when create-lockfiles
+                       (should (string-match-p
+                                (format
+                                 "^%s changed on disk; really edit the 
buffer\\?"
+                                 (if (tramp--test-crypt-p)
+                                     ".+" (file-name-nondirectory tmp-name)))
+                                captured-messages))
+                       (should (file-locked-p tmp-name)))))
+
+                 ;; `save-buffer' removes the file lock.
+                 (cl-letf (((symbol-function 'yes-or-no-p) 
#'tramp--test-always)
+                           ((symbol-function 'read-char-choice)
+                            (lambda (&rest _) ?y)))
+                   (save-buffer))
+                 (should-not (file-locked-p tmp-name))))
+
+           ;; Cleanup.
+           (set-buffer-modified-p nil)
+           (ignore-errors (delete-file tmp-name))
+           (tramp-cleanup-connection
+            tramp-test-vec 'keep-debug 'keep-password)))))))
+
+;; The functions were introduced in Emacs 26.1.
 (ert-deftest tramp-test40-make-nearby-temp-file ()
   "Check `make-nearby-temp-file' and `temporary-file-directory'."
   (skip-unless (tramp--test-enabled))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]