Skip to content

Report branch and tag names unprefixed when a branch and tag share a name [patch] - #181

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/137-ambiguous-ref-names
Oct 6, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/137-ambiguous-ref-names

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #137

What changed

When the shortest name would be ambiguous, %(refname:short) and %(upstream:short) keep part of the ref prefix. This caused two problems:

  • A branch and a tag both called v1 came back as heads/v1 and tags/v1.
  • A local branch called origin/main caused the remote-tracking branch, and every branch's Upstream, to come back as remotes/origin/main.

git rejects names with that leftover prefix when they are passed back to it.

ForEachRefFormat and ForEachTagFormat now read names with :lstrip=2, which always strips exactly refs/heads/, refs/remotes/ or refs/tags/. The parsers are unchanged apart from a comment. Local and remote branches are still told apart by the full refname in field 0, and refs/remotes/<remote>/HEAD is still skipped.

Tests

Two new integration tests in GitRoundTripTests run against real git:

  • BranchAndTagSharingANameAreBothReportedByThatNameAsync: a branch and a tag both named v1 are reported as v1, and deleting each by its reported name succeeds.
  • LocalBranchNamedLikeARemoteBranchLeavesTheRemoteNameAndUpstreamIntactAsync: with a local origin/main next to refs/remotes/origin/main, the remote branch is named origin/main and main's upstream is origin/main.

GitBranchListBuilderTests now expects the new format string.

Checked with git 2.43:

  • With the old format strings, both new tests fail. With the fix, they pass.
  • Full suite: 741 of 741 passed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01W83XxSnDX5Fu4sVPDKjXem


Generated by Claude Code

…name [patch]

%(refname:short) keeps part of the prefix whenever the shortest name is
ambiguous, so a branch and a tag both called v1 came back as heads/v1 and
tags/v1, and a local branch called origin/main turned the remote-tracking
branch and every upstream into remotes/origin/main. None of those names can
be passed back to git. Read names with :lstrip=2 instead, which always strips
exactly refs/heads/, refs/remotes/ or refs/tags/.

Fixes #137

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01W83XxSnDX5Fu4sVPDKjXem
@sonarqubecloud

sonarqubecloud Bot commented Oct 6, 2026

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 9f7b671 into main Oct 6, 2026
16 checks passed
@matt-edmondson
matt-edmondson deleted the fix/137-ambiguous-ref-names branch October 6, 2026 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Branches()/Tags() report "heads/v1" / "tags/v1" when a branch and a tag share a name, so the name can't be passed back to git

2 participants