Subject: Re* [PATCH v3 2/2] doc: revert: add discussion

From: Junio C Hamano <[email-masked]>
Date: Fri, 11 Aug 2023 10:44:50 -0700

Junio C Hamano <[email-masked]> writes:

> Linus Arver <[email-masked]> writes:
>
>> Oswald Buddenhagen <[email-masked]> writes:
>>
>>> while thinking about what to write, i came up with an idea for another
>>> improvement: with (implicit) --edit, the template message would end up
>>> being:
>>>
>>>  This reverts commit <sha1>,
>>>  because <PUT REASON HERE>.
>>
>> This sounds great to me.
>
> Oh, absolutely.  I rarely do a revert myself (other than reverting a
> premature merge out of 'next'), but giving a better instruction in
> the commit log editor buffer as template is a very good idea.

It might be just the matter of doing something like the attached
patch on top of Oswald's, reusing the existing code to instruct the
user to describe the reversion.

------- >8 ------------- >8 ------------- >8 ------------- >8 -------
Subject: [PATCH 3/2] revert: force explaining overly complex revert chain

Once we revert reverts of revert and reach "Reapply "Reapply "..."",
it becomes too unweirdly to read a reversion of such a comit.

We instruct the user to explain why the reversion is done in their
own words when using the revert.reference mode, and the instruction
applies equally for such an overly complex revert chain.  The
rationale for such a sequence of events should be recorded to help
future developers.

Building on top of the recent Oswald's work to turn "revert revert"
into "reapply", let's turn the reference mode automatically on in
such a case.

Signed-off-by: Junio C Hamano <[email-masked]>
---

 * I left the reference to the second parent to honor the command
   line option and configuration variable even when this new
   mechanism kicks in and this is very much deliberate.  As a commit
   that is a revert (or reapply) should be single parent (because a
   revert of a merge is a single parent commit), the choice does not
   make any difference in practice.

 sequencer.c                   | 16 +++++++++++-----
 t/t3501-revert-cherry-pick.sh | 11 ++++++++++-
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git c/sequencer.c w/sequencer.c
index 7dc13fdcca..43bb558518 100644
--- c/sequencer.c
+++ w/sequencer.c
@@ -2130,10 +2130,10 @@ static int should_edit(struct replay_opts *opts) {
 	return opts->edit;
 }
 
-static void refer_to_commit(struct replay_opts *opts,
+static void refer_to_commit(int use_reference,
 			    struct strbuf *msgbuf, struct commit *commit)
 {
-	if (opts->commit_use_reference) {
+	if (use_reference) {
 		struct pretty_print_context ctx = {
 			.abbrev = DEFAULT_ABBREV,
 			.date_mode.type = DATE_SHORT,
@@ -2250,12 +2250,18 @@ static int do_pick_commit(struct repository *r,
 
 	if (command == TODO_REVERT) {
 		const char *orig_subject;
+		int use_reference = opts->commit_use_reference;
 
 		base = commit;
 		base_label = msg.label;
 		next = parent;
 		next_label = msg.parent_label;
-		if (opts->commit_use_reference) {
+
+		if (starts_with(msg.subject, "Reapply \"Reapply \""))
+			/* fifth time is too many - force reference format*/
+			use_reference = 1;
+
+		if (use_reference) {
 			strbuf_addstr(&msgbuf,
 				"# *** SAY WHY WE ARE REVERTING ON THE TITLE LINE ***");
 		} else if (skip_prefix(msg.subject, "Revert \"", &orig_subject) &&
@@ -2273,11 +2279,11 @@ static int do_pick_commit(struct repository *r,
 			strbuf_addstr(&msgbuf, "\"");
 		}
 		strbuf_addstr(&msgbuf, "\n\nThis reverts commit ");
-		refer_to_commit(opts, &msgbuf, commit);
+		refer_to_commit(use_reference, &msgbuf, commit);
 
 		if (commit->parents && commit->parents->next) {
 			strbuf_addstr(&msgbuf, ", reversing\nchanges made to ");
-			refer_to_commit(opts, &msgbuf, parent);
+			refer_to_commit(opts->commit_use_reference, &msgbuf, parent);
 		}
 		strbuf_addstr(&msgbuf, ".\n");
 	} else {
diff --git c/t/t3501-revert-cherry-pick.sh w/t/t3501-revert-cherry-pick.sh
index 7011e3a421..7a8715d3f4 100755
--- c/t/t3501-revert-cherry-pick.sh
+++ w/t/t3501-revert-cherry-pick.sh
@@ -190,7 +190,16 @@ test_expect_success 'title of fresh reverts' '
 	git revert --no-edit HEAD &&
 	echo "Revert \"Reapply \"B\"\"" >expect &&
 	git log -1 --pretty=%s >actual &&
-	test_cmp expect actual
+	test_cmp expect actual &&
+	git revert --no-edit HEAD &&
+	echo "Reapply \"Reapply \"B\"\"" >expect &&
+	git log -1 --pretty=%s >actual &&
+	test_cmp expect actual &&
+
+	# Give the stronger instruction for unusually complex case
+	git revert --no-edit HEAD &&
+	git log -1 --pretty=%s >actual &&
+	grep -F -e "# *** SAY WHY WE ARE REVERTING" actual
 '
 
 test_expect_success 'title of legacy double revert' '