master 0a714557ebd: vc-dir: Don't resolve DIR to truename unnecessarily

Dmitry Gutov <[email protected]> Fri, 24 Jul 2026 23:45:43 -0400 (EDT)
Newsgroups gmane.emacs.diffs
Message-ID <[email protected]>
branch: master
commit 0a714557ebd1c88a01e006fc1419b61d9807a76a
Author: Dmitry Gutov <[email protected]>
Commit: Dmitry Gutov <[email protected]>

    vc-dir: Don't resolve DIR to truename unnecessarily
    
    * lisp/vc/vc-dir.el (vc-dir): Use DIR without resolving truename
    if the responsible VC backend is found.
    (https://lists.gnu.org/archive/html/emacs-devel/2026-07/msg00147.html)
---
 etc/NEWS          |  7 +++++++
 lisp/vc/vc-dir.el | 23 +++++++++++++++--------
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index d8d1daaef95..653dedda04b 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -150,6 +150,13 @@ includes a message saying so, with a button to override it.  You can
 customize the new user option 'vc-dir-process-output-limit' to control
 how early to stop, and to disable this feature.
 
+---
+*** M-x VC-Dir resolves symbolic link only if the directory has no backend
+When called interatively, 'vc-dir' checks if the passed directory has no
+VC backend.  And if its truename does and 'vc-follow-symlinks' is
+non-nil, the truename is used instead.  Before this change, the truename
+was used unconditionally.
+
 +++
 *** Improved creation of commit log entry from ChangeLog.
 When VC detects that all log entries for the current changeset come from
diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el
index 0b0671a8030..e71e91e3c0a 100644
--- a/lisp/vc/vc-dir.el
+++ b/lisp/vc/vc-dir.el
@@ -1995,14 +1995,21 @@ These are the commands available for use in the file status buffer:
 
   (interactive
    (list
-    ;; When you hit C-x v d in a visited VC file,
-    ;; the *vc-dir* buffer visits the directory under its truename;
-    ;; therefore it makes sense to always do that.
-    ;; Otherwise if you do C-x v d -> C-x C-f -> C-x v d
-    ;; you may get a new *vc-dir* buffer, different from the original
-    (file-truename (read-directory-name "VC status for directory: "
-					(vc-root-dir) nil t
-					nil))
+    (let ((dir (read-directory-name "VC status for directory: "
+                                    (vc-root-dir) nil t
+                                    nil))
+          truename)
+      ;; Try to match the result of `vc-refresh-state' in a file buffer.
+      ;; Otherwise if you do C-x v d -> C-x C-f -> C-x v d you may get a
+      ;; new *vc-dir* buffer, different from the original.
+      ;; If DIR has no VC backend but its truename does, use that
+      ;; instead of DIR.
+      (if (and vc-follow-symlinks
+               (not (vc-responsible-backend dir t))
+               (not (equal dir (setq truename (file-truename dir))))
+               (vc-responsible-backend truename t))
+          truename
+        dir))
     (if current-prefix-arg
 	(intern
 	 (completing-read