Subject: Re: bug#73387: 30.0.90; C-x v v in diff-mode doesn't work after C-c C-n

From: Dmitry Gutov <[email-masked]>
Date: Tue, 24 Sep 2024 01:41:00 +0300

Hi!

On 20/09/2024 19:08, Sean Whitton wrote:
> X-debbugs-cc: [email-masked], [email-masked], [email-masked]
> 
> Hello,
> 
> If you do C-c C-n in a diff-mode buffer with multiple hunks, a
> subsequent C-x v v signals a user-error from diff-file-next.  I think
> that the bug is in how diff-vc-deduce-fileset invokes diff-file-next.
> I'm not sure exactly how to rework diff-vc-deduce-fileset.
> 
> It would be nice to fix this because then C-c C-n C-x v v would be a
> convenient way to commit just a single hunk.

This seems to work:

diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 4810b9ce01c..dc59621200c 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -3133,11 +3133,16 @@ diff-syntax-fontify-props
  ;;;###autoload
  (defun diff-vc-deduce-fileset ()
    (let ((backend (vc-responsible-backend default-directory))
+        (start (point-min))
+        (end (point-max))
          files)
      (save-excursion
-      (goto-char (point-min))
-      (while (progn (diff-file-next) (not (eobp)))
-        (push (diff-find-file-name nil t) files)))
+      (save-restriction
+        (widen)
+        (goto-char start)
+        (diff-beginning-of-file-and-junk)
+        (while (progn (diff-file-next) (<= (point) end))
+          (push (diff-find-file-name nil t) files))))
      (list backend (delete nil (nreverse files)) nil nil 'patch)))

  (defun diff--filter-substring (str)

But to really commit the narrowed diff I think you'll need to do 
something about this line in vc-next-action

      ((eq model 'patch)
       (vc-checkin files backend nil nil nil (buffer-string)))

...to specify altered buffer contents as the diff to use.