Subject: bug#58383: 29.0.50; Make it easier to invert vc-prepare-patches-separately

From: Philip Kaludercic <[email-masked]>
Date: Sun, 13 Nov 2022 13:56:38 +0000

Sean Whitton <[email-masked]> writes:

> Hello,
>
> On Fri 11 Nov 2022 at 06:32AM GMT, Philip Kaludercic wrote:
>
>> Sean Whitton <[email-masked]> writes:
>>
>>>>> Typically you wouldn't want to format patches across a merge, so I would
>>>>> suggest raising an error.
>>>>
>>>> And this is something I don't think can be /expressed/ using vc, because
>>>> while I can collect a number of revisions using `previous-revision',
>>>> there is no general way to verify if a commit is a merge commit.
>>>
>>> Can we do that part on a VCS-by-VCS basis?  Default to just calling
>>> previous-revision and hoping for the best, but giving vc-git.el a chance
>>> to raise an error.
>>
>> I guess that would be possible, though it will probably require a new
>> VC method :/  The new `prepare-patch' takes a revision, so it doesn't
>> make sense to pass it a number and have it return multiple patches.
>>
>> Perhaps it will be easier/cleaner to just accept that avoiding merge
>> revisions is the users responsibility.
>
> Sounds reasonable -- it can always be enhanced later in a way that's
> backwards-compatible.
>
>> But just to have mentioned it: Do you know that you can mark revisions
>> in log-view and then vc-prepare-patches will use these as the default
>> input when prompting for revisions?
>
> Yeah, but marking in those buffers is way more awkward than marking in,
> e.g., dired, and I usually know how many commits I want to send without
> looking at the log.

How does the following look like:

diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 513fbb23fe..0b8a8d83e3 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -3391,14 +3391,24 @@ vc-prepare-patch
 as the default subject for the message (and it will be prompted
 for when called interactively).  Otherwise a separate message
 will be composed for each revision, with SUBJECT derived from the
-invidividual commits.
-
-When invoked interactively in a Log View buffer with marked
-revisions, those revisions will be used."
+invidividual commits.  When invoked with a numerical prefix
+argument, the last N revisions will be used.  When invoked
+interactively in a Log View buffer with marked revisions, those
+revisions will be used."
   (interactive
    (let ((revs (vc-read-multiple-revisions
                 "Revisions: " nil nil nil
-                (or (and-let* ((revs (log-view-get-marked)))
+                (or (and-let* ((arg current-prefix-arg)
+                               (fs (vc-deduce-fileset t)))
+                      (cl-loop with file = (caadr fs)
+                               repeat (prefix-numeric-value arg)
+                               for rev = (vc-working-revision file)
+                               then (vc-call-backend
+                                     (car fs) 'previous-revision
+                                     file rev)
+                               when rev collect it into revs
+                               finally return (mapconcat #'identity revs ",")))
+                    (and-let* ((revs (log-view-get-marked)))
                       (mapconcat #'identity revs ","))
                     (and-let* ((file (buffer-file-name)))
                       (vc-working-revision file)))))