git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "SZEDER Gábor" <szeder.dev@gmail.com>
To: git@vger.kernel.org
Cc: "Derrick Stolee" <derrickstolee@github.com>,
	"Junio C Hamano" <gitster@pobox.com>,
	"SZEDER Gábor" <szeder.dev@gmail.com>
Subject: [PATCH 6/6] sequencer: fail early if invalid ref is given to 'update-ref' instruction
Date: Fri, 30 Sep 2022 16:09:48 +0200	[thread overview]
Message-ID: <20220930140948.80367-7-szeder.dev@gmail.com> (raw)
In-Reply-To: <20220930140948.80367-1-szeder.dev@gmail.com>

Users can add their own 'update-ref <ref>' instructions to the rebase
todo list, which also gives them the possibility to specify an invalid
ref as argument.  Now, while git does catch any invalid ref and errors
out, it does so at the very end of the rebase process, when the
invalid ref causes the transaction updating all involved refs to fail,
leaving users on their own to figure out where each of those refs
should point now and to update them themselves.

Let's do better, and catch invalid refs early on by calling
check_refname_format() for the argument of each 'update-ref'
instruction while parsing the todo file.  This way 'git rebase' would
error out right after the user finished editing the todo file, and
would show the same generic advice to rectify the situation that is
shown e.g.  after an unknown instruction or a missing argument for a
'pick' instruction, etc.

Furthermore, require that all refs given to 'update-ref' instructions
live under the "refs/" hierarchy.  The argument of the 'update-ref'
instruction is treated as a fully qualified ref, so if the todo list
were to contain the 'update-ref foo' instruction, then 'git rebase'
would happily create the ref file '.git/foo' containing the
appropriate object id.  This is most likely not what the user wanted
and will cause confusion.  I assume it's much more probable that some
users simply forgot about the "refs/heads/" prefix than that they have
a use-case for using 'git rebase' to create/update a ref outside the
"refs/" hierarchy.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
 sequencer.c                   | 19 ++++++++++++++++++-
 t/t3404-rebase-interactive.sh | 28 ++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/sequencer.c b/sequencer.c
index f1732f88f3..ababfa6352 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2522,7 +2522,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
 			     command_to_string(item->command));
 
 	if (item->command == TODO_EXEC || item->command == TODO_LABEL ||
-	    item->command == TODO_RESET || item->command == TODO_UPDATE_REF) {
+	    item->command == TODO_RESET) {
 		item->commit = NULL;
 		item->arg_offset = bol - buf;
 		item->arg_len = (int)(eol - bol);
@@ -2556,6 +2556,23 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
 		}
 	}
 
+	if (item->command == TODO_UPDATE_REF) {
+		struct strbuf ref = STRBUF_INIT;
+		int ret = 0;
+
+		item->commit = NULL;
+		item->arg_offset = bol - buf;
+		item->arg_len = (int)(eol - bol);
+
+		strbuf_add(&ref, bol, item->arg_len);
+		if (!starts_with(ref.buf, "refs/") ||
+		    check_refname_format(ref.buf, 0))
+			ret = error(_("invalid ref for update-ref instruction: %s"), ref.buf);
+
+		strbuf_release(&ref);
+		return ret;
+	}
+
 	end_of_object_name = (char *) bol + strcspn(bol, " \t\n");
 	saved = *end_of_object_name;
 	*end_of_object_name = '\0';
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 2e081b3914..b97f1e8b31 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -1964,6 +1964,34 @@ test_expect_success 'respect user edits to update-ref steps' '
 	test_cmp_rev HEAD refs/heads/no-conflict-branch
 '
 
+test_expect_success 'update-refs with invalid refs' '
+	cat >fake-todo-4 <<-EOF &&
+	update-ref refs/heads/foo..bar
+	update-ref refs/heads/foo.lock
+	update-ref foo
+	update-ref foo/bar
+	pick $(git rev-parse HEAD)
+	EOF
+	cat >expect.err <<-EOF &&
+	error: invalid ref for update-ref instruction: refs/heads/foo..bar
+	error: invalid line 1: update-ref refs/heads/foo..bar
+	error: invalid ref for update-ref instruction: refs/heads/foo.lock
+	error: invalid line 2: update-ref refs/heads/foo.lock
+	error: invalid ref for update-ref instruction: foo
+	error: invalid line 3: update-ref foo
+	error: invalid ref for update-ref instruction: foo/bar
+	error: invalid line 4: update-ref foo/bar
+	You can fix this with ${SQ}git rebase --edit-todo${SQ} and then run ${SQ}git rebase --continue${SQ}.
+	Or you can abort the rebase with ${SQ}git rebase --abort${SQ}.
+	EOF
+	test_when_finished "test_might_fail git rebase --abort" &&
+	(
+		set_replace_editor fake-todo-4 &&
+		test_must_fail git rebase -i HEAD^ 2>err
+	) &&
+	test_cmp expect.err err
+'
+
 test_expect_success REFFILES '--update-refs: check failed ref update' '
 	git checkout -B update-refs-error no-conflict-branch &&
 	git branch -f base HEAD~4 &&
-- 
2.38.0.rc2.542.g9b62912f7f


  parent reply	other threads:[~2022-09-30 14:12 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-30 14:09 [PATCH 0/6] rebase --update-refs: smooth out some rough edges SZEDER Gábor
2022-09-30 14:09 ` [PATCH 1/6] t2407-worktree-heads.sh: remove outdated loop SZEDER Gábor
2022-09-30 14:09 ` [PATCH 2/6] t3404-rebase-interactive: mark a test with REFFILES prereq SZEDER Gábor
2022-09-30 16:46   ` Ævar Arnfjörð Bjarmason
2022-10-05 16:45     ` Junio C Hamano
2022-09-30 14:09 ` [PATCH 3/6] rebase -i: emphasize that 'update-ref' expects a fully-qualified ref SZEDER Gábor
2022-09-30 14:09 ` [PATCH 4/6] sequencer: avoid empty lines after 'update-ref' instructions SZEDER Gábor
2022-09-30 17:18   ` Derrick Stolee
2022-10-05 16:49     ` Junio C Hamano
2022-09-30 14:09 ` [PATCH 5/6] sequencer: duplicate the result of resolve_ref_unsafe() SZEDER Gábor
2022-09-30 16:45   ` Ævar Arnfjörð Bjarmason
2022-09-30 16:51   ` Ævar Arnfjörð Bjarmason
2022-09-30 17:23   ` Derrick Stolee
2022-10-09 17:23     ` SZEDER Gábor
2022-09-30 14:09 ` SZEDER Gábor [this message]
2022-09-30 17:09   ` [PATCH 6/6] sequencer: fail early if invalid ref is given to 'update-ref' instruction Ævar Arnfjörð Bjarmason
2022-09-30 17:29 ` [PATCH 0/6] rebase --update-refs: smooth out some rough edges Derrick Stolee
2022-10-01 16:31   ` SZEDER Gábor
2022-10-01 16:53     ` Junio C Hamano
2022-10-05 17:14   ` Junio C Hamano

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=20220930140948.80367-7-szeder.dev@gmail.com \
    --to=szeder.dev@gmail.com \
    --cc=derrickstolee@github.com \
    --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).