Subject: [PATCH] Handle renamed files when cycling through revisions

From: Jakub Ječmínek <[email-masked]>
Date: Mon, 30 Jun 2025 22:29:43 +0200

* lisp/vc/vc-git.el (vc-git-registered,vc-git-annotate-command):
Update the FILE argument passed to 'vc-git-annotate-command'
based on whether FILE exists in the current revision. If it
doesn't, look up its new name. (Bug#26345)
---
What do you think about the patch below?

 lisp/vc/vc-git.el | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index e27798913fe..8f10893d0ba 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -289,12 +289,13 @@ vc-git-update-on-retrieve-tag
 ;;;###autoload         (load "vc-git" nil t)
 ;;;###autoload         (vc-git-registered file))))
 
-(defun vc-git-registered (file)
+(defun vc-git-registered (file &optional rev)
   "Check whether FILE is registered with git."
   (let ((dir (vc-git-root file)))
     (when dir
       (with-temp-buffer
         (let* (process-file-side-effects
+               (rev (or rev "HEAD"))
                ;; Do not use the `file-name-directory' here: git-ls-files
                ;; sometimes fails to return the correct status for relative
                ;; path specs.
@@ -306,7 +307,7 @@ vc-git-registered
                       ;; If result is empty, use ls-tree to check for deleted
                       ;; file.
                       (when (eq (point-min) (point-max))
-                        (vc-git--out-ok "ls-tree" "--name-only" "-z" "HEAD"
+                        (vc-git--out-ok "ls-tree" "--name-only" "-z" rev
                                         "--" name))
                       (buffer-string))))
           (and str
@@ -1860,7 +1861,12 @@ vc-git-revision-completion-table
 
 (defun vc-git-annotate-command (file buf &optional rev)
   (vc-git--asciify-coding-system)
-  (let ((name (file-relative-name file)))
+  ;; If the file does not exist in the tree, it most likely means
+  ;; that it has been renamed.  Bug#26345
+  (let* ((file (if (vc-git-registered file rev)
+                   file
+                 (cdr (assoc file (vc-git-file-name-changes rev)))))
+         (name (file-relative-name file)))
     (apply #'vc-git-command buf 'async nil "blame" "--date=short"
 	   (append (vc-switches 'git 'annotate)
 		   (list rev "--" name)))))
-- 
2.49.0