Skip to content

rebase: handle --update-refs branch symrefs#2126

Open
sluongng wants to merge 1 commit into
gitgitgadget:masterfrom
sluongng:sl/rebase-update-refs-symrefs
Open

rebase: handle --update-refs branch symrefs#2126
sluongng wants to merge 1 commit into
gitgitgadget:masterfrom
sluongng:sl/rebase-update-refs-symrefs

Conversation

@sluongng
Copy link
Copy Markdown

@sluongng sluongng commented May 27, 2026

git rebase --update-refs can fail after the normal rebase path has
updated the current branch when another local branch is a symref to it.
This can happen during a default-branch rename where refs/heads/main
points at refs/heads/master while users migrate.

The sequencer queues update-ref commands from local branch decorations.
Commit 106b688 (rebase: ignore non-branch update-refs) filters out
decorations that are not local branches, such as HEAD and tags. A branch
symref is different: it is still a local branch decoration under
refs/heads/, but it is an alias rather than a concrete branch to update.

Queuing the alias by its literal name makes the final update dereference
it back to the current branch and fail the old-OID check because that
branch moved earlier in the rebase. Resolve local branch symrefs to
their referents before queuing update-ref commands. Skip aliases of HEAD
and duplicate referents, leaving one old-OID-checked update for each
concrete branch.

Changes since v1:

  • Squashed the regression test and fix into a single patch.
  • Clarified how this builds on 106b688:
    non-local decorations are already filtered, and this patch handles the
    remaining local branch decorations that are symref aliases.

cc: "Kristoffer Haugsbakk" kristofferhaugsbakk@fastmail.com

@sluongng sluongng force-pushed the sl/rebase-update-refs-symrefs branch from 9938d7e to 0ab0a71 Compare May 27, 2026 14:14
@sluongng
Copy link
Copy Markdown
Author

/preview

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 27, 2026

Preview email sent as pull.2126.git.1779908024.gitgitgadget@gmail.com

@sluongng
Copy link
Copy Markdown
Author

/preview

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 28, 2026

Preview email sent as pull.2126.git.1779943633.gitgitgadget@gmail.com

@sluongng
Copy link
Copy Markdown
Author

/preview

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 28, 2026

Preview email sent as pull.2126.git.1779943735.gitgitgadget@gmail.com

@sluongng
Copy link
Copy Markdown
Author

/preview

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 28, 2026

Preview email sent as pull.2126.git.1779944585.gitgitgadget@gmail.com

@sluongng
Copy link
Copy Markdown
Author

/submit

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 28, 2026

Submitted as pull.2126.git.1779946921.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-2126/sluongng/sl/rebase-update-refs-symrefs-v1

To fetch this version to local tag pr-2126/sluongng/sl/rebase-update-refs-symrefs-v1:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-2126/sluongng/sl/rebase-update-refs-symrefs-v1

Comment thread sequencer.c
@@ -6445,28 +6445,67 @@ static int add_decorations_to_list(const struct commit *commit,
struct todo_add_branch_context *ctx)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Kristoffer Haugsbakk" wrote on the Git mailing list (how to reply to this email):

On Thu, May 28, 2026, at 07:42, Son Luong Ngoc via GitGitGadget wrote:
>[snip]
> -test_expect_failure '--update-refs skips branch symrefs to current branch' '
> +test_expect_success '--update-refs skips branch symrefs to current branch' '
>  	test_when_finished "
>  		test_might_fail git rebase --abort &&
>  		git checkout primary &&

This style of fixing a bug by:

• Add failing test `test_expect_failure` in the first commit
• Fix the bug in the next commit and flip to `test_expect_success`

Is legitimate and makes it easier to verify that the test really
exercises the regression. But in this project it is preferred to
just do the bug fix + regression test in one patch.

See https://lore.kernel.org/git/xmqqfrdk3aqy.fsf@gitster.g/

> --
> gitgitgadget

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 28, 2026

User "Kristoffer Haugsbakk" <kristofferhaugsbakk@fastmail.com> has been added to the cc: list.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 28, 2026

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Son Luong Ngoc via GitGitGadget" <gitgitgadget@gmail.com> writes:

> git rebase --update-refs can fail after the normal rebase path has
> successfully updated the current branch when another local branch is a
> symbolic ref to it.
>
> One practical way to arrive at that setup is a default branch rename from
> master to main. While the migration is in progress, a user may keep
> refs/heads/main as a symbolic ref to refs/heads/master so that both names
> continue to work locally.
>
> If pull.rebase is enabled, a plain git pull can then finish the rebase of
> master and still fail while trying to update the main alias. The reported
> failure looked like this, with line breaks adjusted for the cover letter:
>
> Successfully rebased and updated refs/heads/master.
> error: update_ref failed for ref 'refs/heads/main':
> cannot lock ref 'refs/heads/main':
> is at fc2c7bd5f17abec7861ef759edcd33a1e16662a1
> but expected 531cabdfb49098d6ffa502ed4bf91d1b35edfcfa
> Updated the following refs with --update-refs:
> Failed to update the following refs with --update-refs:
>         refs/heads/main

I vaguely recall we saw a different topic that dealt with a
situation somewhat similar to this topic (I think it was about
'describe' giving a name that is not a branch).  How would this mesh
with what the other topic wanted to do?  Instead of filtering out
non-branch names (which the other topic did), here we want to filter
out names that are not concrete branches but pointers to something
else.  Would it mean that the logic here is more broad (i.e., both
wants to filter out names of non-branches), making the other topic
unnecessary?

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 29, 2026

This patch series was integrated into seen via git@d871d43.

@gitgitgadget gitgitgadget Bot added the seen label May 29, 2026
@sluongng sluongng force-pushed the sl/rebase-update-refs-symrefs branch from 0ab0a71 to c1e8828 Compare May 29, 2026 13:41
@sluongng
Copy link
Copy Markdown
Author

/preview

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 29, 2026

Preview email sent as pull.2126.v2.git.1780062147590.gitgitgadget@gmail.com

git rebase --update-refs can fail after the normal rebase path has
updated the current branch when another local branch is a symref to it.
This can happen during a default-branch rename where refs/heads/main
points at refs/heads/master while users migrate.

The sequencer queues update-ref commands from local branch decorations.
Commit 106b688 (rebase: ignore non-branch update-refs) filters out
decorations that are not local branches, such as HEAD and tags. A branch
symref is different: it is still a local branch decoration under
refs/heads/, but it is an alias rather than a concrete branch to update.

Queuing the alias by its literal name makes the final update dereference
it back to the current branch and fail the old-OID check because that
branch moved earlier in the rebase. Resolve local branch symrefs to
their referents before queuing update-ref commands. Skip aliases of HEAD
and duplicate referents, leaving one old-OID-checked update for each
concrete branch.

Signed-off-by: Son Luong Ngoc <sluongng@gmail.com>
@sluongng sluongng force-pushed the sl/rebase-update-refs-symrefs branch from c1e8828 to b59eb4e Compare May 29, 2026 15:23
@sluongng
Copy link
Copy Markdown
Author

/preview

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 29, 2026

Preview email sent as pull.2126.v2.git.1780068269833.gitgitgadget@gmail.com

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 30, 2026

This branch is now known as sn/rebase-update-refs-symrefs.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 30, 2026

This patch series was integrated into seen via git@eb72804.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant