git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Johannes Altmanninger <aclopte@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: Erik Cervin Edin <erik@cervined.in>,
	git@vger.kernel.org, Johannes Altmanninger <aclopte@gmail.com>
Subject: [PATCH v3] sequencer: avoid dropping fixup commit that targets self via commit-ish
Date: Sat, 24 Sep 2022 17:29:04 -0500	[thread overview]
Message-ID: <20220924222904.1784975-1-aclopte@gmail.com> (raw)
In-Reply-To: <xmqqpmfnxl1o.fsf@gitster.g>

Commit 68d5d03bc4 (rebase: teach --autosquash to match on sha1 in
addition to message, 2010-11-04) taught autosquash to recognize
subjects like "fixup! 7a235b" where 7a235b is an OID-prefix. It
actually did more than advertised: 7a235b can be an arbitrary
commit-ish (as long as it's not trailed by spaces).

Accidental(?) use of this secret feature revealed a bug where we
would silently drop a fixup commit. The bug can also be triggered
when using an OID-prefix but that's unlikely in practice.

Let the commit with subject "fixup! main" be the tip of the "main"
branch. When computing the fixup target for this commit, we find
the commit itself. This is wrong because, by definition, a fixup
target must be an earlier commit in the todo list. We wrongly find
the current commit because we added it to the todo list prematurely.
Avoid these fixup-cycles by only adding the current commit to the
todo list after we have finished looking for the fixup target.

Reported-by: Erik Cervin Edin <erik@cervined.in>
Signed-off-by: Johannes Altmanninger <aclopte@gmail.com>
---
 sequencer.c                  |  4 ++--
 t/t3415-rebase-autosquash.sh | 13 +++++++++++++
 2 files changed, 15 insertions(+), 2 deletions(-)

Changes since v2:
- minor commit message rewording and clarification
- dropped a test that was based on a wrong understanding of --autosquash.

  I saw b425461cb5 (SQUASH??? resurrect previous version of the tests,
  2022-09-21) today. I'm leaning towards not adding them back because
  those tests were only added to reflect the current behavior.  but that
  behavior is not something I care about.
  We might even want to change this behavior, by restricting OID fixup
  targets to SHAs only. So I don't think these tests are desirable,
  unless they help others understand the current state of affairs?

1:  37e00c51bd ! 1:  a25c886a78 sequencer: avoid dropping fixup commit that targets self via commit-ish
    @@ Commit message
         would silently drop a fixup commit. The bug can also be triggered
         when using an OID-prefix but that's unlikely in practice.
     
    -    Given a commit with subject "fixup! main" that is the tip of the
    -    branch "main". When computing the fixup target for this commit, we
    -    find the commit itself. This is wrong because, by definition, a fixup
    +    Let the commit with subject "fixup! main" be the tip of the "main"
    +    branch. When computing the fixup target for this commit, we find
    +    the commit itself. This is wrong because, by definition, a fixup
         target must be an earlier commit in the todo list. We wrongly find
         the current commit because we added it to the todo list prematurely.
    -    Avoid these fixup-cycles by only adding the current commit after we
    -    have finished finding its target.
    +    Avoid these fixup-cycles by only adding the current commit to the
    +    todo list after we have finished looking for the fixup target.
     
         Reported-by: Erik Cervin Edin <erik@cervined.in>
     
      ## sequencer.c ##
     @@ sequencer.c: int todo_list_rearrange_squash(struct todo_list *todo_list)
    @@ t/t3415-rebase-autosquash.sh: test_expect_success 'auto squash that matches long
      	test_line_count = 1 actual
      '
      
    -+test_expect_success 'auto squash that matches regex' '
    -+	git reset --hard base &&
    -+	git commit --allow-empty -m "hay needle hay" &&
    -+	git commit --allow-empty -m "fixup! :/needle" &&
    -+	GIT_SEQUENCE_EDITOR="cat >tmp" git rebase --autosquash -i HEAD^^ &&
    -+	sed -ne "/^[^#]/{s/[0-9a-f]\{7,\}/HASH/g;p;}" tmp >actual &&
    -+	cat <<-EOF >expect &&
    -+	pick HASH hay needle hay # empty
    -+	fixup HASH fixup! :/needle # empty
    -+	EOF
    -+	test_cmp expect actual
    -+'
    -+
     +test_expect_success 'auto squash of fixup commit that matches branch name which points back to fixup commit' '
     +	git reset --hard base &&
     +	git commit --allow-empty -m "fixup! self-cycle" &&


diff --git a/sequencer.c b/sequencer.c
index 484ca9aa50..777200a6dc 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -6287,8 +6287,6 @@ int todo_list_rearrange_squash(struct todo_list *todo_list)
 			return error(_("the script was already rearranged."));
 		}
 
-		*commit_todo_item_at(&commit_todo, item->commit) = item;
-
 		parse_commit(item->commit);
 		commit_buffer = logmsg_reencode(item->commit, NULL, "UTF-8");
 		find_commit_subject(commit_buffer, &subject);
@@ -6355,6 +6353,8 @@ int todo_list_rearrange_squash(struct todo_list *todo_list)
 					strhash(entry->subject));
 			hashmap_put(&subject2item, &entry->entry);
 		}
+
+		*commit_todo_item_at(&commit_todo, item->commit) = item;
 	}
 
 	if (rearranged) {
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index 78c27496d6..a364530d76 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -232,6 +232,19 @@ test_expect_success 'auto squash that matches longer sha1' '
 	test_line_count = 1 actual
 '
 
+test_expect_success 'auto squash of fixup commit that matches branch name which points back to fixup commit' '
+	git reset --hard base &&
+	git commit --allow-empty -m "fixup! self-cycle" &&
+	git branch self-cycle &&
+	GIT_SEQUENCE_EDITOR="cat >tmp" git rebase --autosquash -i HEAD^^ &&
+	sed -ne "/^[^#]/{s/[0-9a-f]\{7,\}/HASH/g;p;}" tmp >actual &&
+	cat <<-EOF >expect &&
+	pick HASH second commit
+	pick HASH fixup! self-cycle # empty
+	EOF
+	test_cmp expect actual
+'
+
 test_auto_commit_flags () {
 	git reset --hard base &&
 	echo 1 >file1 &&
-- 
2.37.3.830.gf65be7a4d6


  reply	other threads:[~2022-09-24 22:29 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-17 14:45 [BUG] fixup commit is dropped during rebase if subject = branch name Erik Cervin Edin
2022-09-17 18:04 ` Junio C Hamano
2022-09-18 14:55   ` Erik Cervin Edin
2022-09-17 23:19 ` Johannes Altmanninger
2022-09-18 12:10   ` [PATCH] sequencer: avoid dropping fixup commit that targets self via commit-ish Johannes Altmanninger
2022-09-18 15:05     ` Erik Cervin Edin
2022-09-18 17:54       ` Johannes Altmanninger
2022-09-19  1:11     ` Junio C Hamano
2022-09-19 16:07       ` Junio C Hamano
2022-09-20  3:20         ` Johannes Altmanninger
2022-09-19 16:23       ` Junio C Hamano
2022-09-20  3:11         ` [PATCH v2] " Johannes Altmanninger
2022-09-20  8:26           ` Phillip Wood
2022-09-21 18:47           ` Junio C Hamano
2022-09-22  4:00             ` Johannes Altmanninger
2022-09-22 19:32               ` Junio C Hamano
2022-09-24 22:29                 ` Johannes Altmanninger [this message]
2022-09-19 23:09     ` [PATCH] " Junio C Hamano
2022-09-20  3:27       ` Johannes Altmanninger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220924222904.1784975-1-aclopte@gmail.com \
    --to=aclopte@gmail.com \
    --cc=erik@cervined.in \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).