From 106b6885c7bbaafc863dff0bb5361f906545de5c Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Sun, 10 May 2026 15:41:11 -0700 Subject: [PATCH] rebase: ignore non-branch update-refs The following Git configuration breaks git rebase --update-refs: [rebase] instructionFormat = %s%d The '%d' format requests all available decorations for a commit, filling the global decoration table with all of them, which --update-refs then uses to populate 'update-ref' instructions in the rebase todo list. Specifically, this results in the following instruction: update-ref HEAD The todo parser then rejects the instruction: error: update-ref requires a fully qualified refname e.g. refs/heads/HEAD error: invalid line 3: update-ref HEAD To fix, ignore decorations that are not local branches when scanning through the table. This matches the documented contract: it moves branch refs under refs/heads/ and leaves display-only decorations (HEAD, tags, etc.) alone. Verification: A regression test that fails without this fix is included. Signed-off-by: Abhinav Gupta Signed-off-by: Junio C Hamano --- sequencer.c | 8 +++++++- t/t3404-rebase-interactive.sh | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/sequencer.c b/sequencer.c index 1f492f8460..df5906a64e 100644 --- a/sequencer.c +++ b/sequencer.c @@ -6361,8 +6361,14 @@ static int add_decorations_to_list(const struct commit *commit, /* * If the branch is the current HEAD, then it will be * updated by the default rebase behavior. + * Exclude it from the list of refs to update, + * as well as any non-branch decorations. + * Non-branch decorations may be present if the pretty format + * includes "%d", which would have loaded all refs + * into the global decoration table. */ - if (head_ref && !strcmp(head_ref, decoration->name)) { + if ((head_ref && !strcmp(head_ref, decoration->name)) || + (decoration->type != DECORATION_REF_LOCAL)) { decoration = decoration->next; continue; } diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index e778dd8ae4..217184fb86 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -1954,6 +1954,24 @@ test_expect_success '--update-refs adds commands with --rebase-merges' ' ) ' +test_expect_success '--update-refs ignores non-branch decorations' ' + test_when_finished "git branch -D update-refs" && + test_when_finished "git checkout primary" && + git checkout -B update-refs no-conflict-branch && + ( + set_cat_todo_editor && + + # rebase.instructionFormat=%d loads normal log decorations before + # --update-refs adds its branch placeholders so we must ignore + # all non-local decorations. + test_must_fail git -c rebase.instructionFormat="%s%d" \ + rebase -i --update-refs HEAD^ >todo + ) && + grep ^update-ref todo >actual && + test_write_lines "update-ref refs/heads/no-conflict-branch" >expect && + test_cmp expect actual +' + test_expect_success '--update-refs updates refs correctly' ' git checkout -B update-refs no-conflict-branch && git branch -f base HEAD~4 && -- 2.47.3