From c244314974a32478b3a28558a1eff628b8da2dce Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Mon, 8 Jun 2026 15:29:12 +0100 Subject: [PATCH] Fix recurrence of bug#80803 after changes in bug#80967 * lisp/vc/vc-dir.el (vc-dir-resynch-file): Pass only truenames to vc-dir-recompute-file-state. * test/lisp/vc/vc-tests/vc-test-misc.el (vc-git): Require. (vc-test-vc-dir-on-symlink): New test. --- lisp/vc/vc-dir.el | 21 ++++++------- test/lisp/vc/vc-tests/vc-test-misc.el | 45 +++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index 27513f463bd..aa4bf7b2ec8 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -1313,8 +1313,7 @@ that file." (defun vc-dir-resynch-file (&optional fname) "Update the entries for FNAME in any directory buffers that list it." - (let* ((file (or fname buffer-file-name)) - (file-tn (file-truename file)) + (let* ((file (file-truename (or fname buffer-file-name))) (drop '())) (save-current-buffer ;; look for a vc-dir buffer that might show this file. @@ -1333,20 +1332,20 @@ that file." ;; `default-directory' in order to do its work, ;; but that's irrelevant to us here. (buffer-local-toplevel-value 'default-directory)))) - (when (file-in-directory-p file-tn ddir) - (if (file-directory-p file-tn) + (when (file-in-directory-p file ddir) + (if (file-directory-p file) (progn - (vc-dir-resync-directory-files file-tn) + (vc-dir-resync-directory-files file) (ewoc-set-hf vc-ewoc (vc-dir-headers vc-dir-backend ddir) "")) (let* ((complete-state - ;; Pass FILE not FILE-TN here. See bug#80967. - (vc-dir-recompute-file-state file ddir)) + (vc-dir-recompute-file-state file + (file-truename ddir))) (state (cadr complete-state))) - (vc-dir-update - (list complete-state) - status-buf (or (not state) - (eq state 'up-to-date))))))))))) + (vc-dir-update (list complete-state) + status-buf + (or (not state) + (eq state 'up-to-date))))))))))) ;; Remove out-of-date entries from vc-dir-buffers. (setq vc-dir-buffers (cl-nset-difference vc-dir-buffers drop :test #'eq)))) diff --git a/test/lisp/vc/vc-tests/vc-test-misc.el b/test/lisp/vc/vc-tests/vc-test-misc.el index 72dc8de22bf..72a65df0fe6 100644 --- a/test/lisp/vc/vc-tests/vc-test-misc.el +++ b/test/lisp/vc/vc-tests/vc-test-misc.el @@ -25,6 +25,7 @@ (require 'ert-x) (require 'vc) +(require 'vc-git) (ert-deftest vc-test-buffer-sync-fileset () "Test `vc-buffer-sync-fileset'." @@ -242,5 +243,49 @@ (should (eq (vc--match-branch-name-regexps "master") 'topic)) (should (eq (vc--match-branch-name-regexps "foo") 'trunk))))) +(ert-deftest vc-test-vc-dir-on-symlink () + "Test VC-Dir on a symlink to a repository. +See bug#80803 and bug#80967." + (skip-unless (executable-find vc-git-program)) + (let ((vc-handled-backends '(Git))) + (ert-with-temp-directory tempdir + (let* ((default-directory tempdir) + (src (expand-file-name "src/" tempdir)) + (dest (expand-file-name "dest/" tempdir)) + (file (expand-file-name "foo" dest)) + file-buf truename-dir symlink-dir) + (make-directory dest) + (let ((default-directory dest) + vc-async-checkin) + (vc-create-repo 'Git) + (write-region "foo\n" nil file nil 'nomessage) + (with-current-buffer (setq file-buf (find-file-noselect file)) + (vc-register `(Git (,file))) + (vc-checkin (list file) 'Git) + (insert "Initial commit") + (let (vc-async-checkin) + (log-edit-done)))) + (make-symbolic-link dest src) + ;; Emulate an interactive call to `vc-dir'. + (vc-dir (file-truename src) 'Git) + (while (vc-dir-busy) (sit-for 0.05)) + (should (equal default-directory dest)) + (setq truename-dir (current-buffer)) + ;; Now a `vc-dir' pointed at the symlink, which is unlike an + ;; interactive call to `vc-dir'. + (vc-dir src 'Git) + (while (vc-dir-busy) (sit-for 0.05)) + (should (equal default-directory src)) + (setq symlink-dir (current-buffer)) + (with-current-buffer file-buf + (insert "bar") + (basic-save-buffer)) + (dolist (buf (list truename-dir symlink-dir)) + (with-current-buffer buf + (should (equal (vc-dir-fileinfo->name + (ewoc-data + (ewoc-nth vc-ewoc 1))) + (file-name-nondirectory file))))))))) + (provide 'vc-test-misc) ;;; vc-test-misc.el ends here