Skip to content

fix(resume): resolve branch names Unicode-normalization-insensitively (NFC/NFD) - #2552

Open
KC1706 wants to merge 1 commit into
entireio:mainfrom
KC1706:kc/2551-normalize-branch-name-resume
Open

KC1706 wants to merge 1 commit into
entireio:mainfrom
KC1706:kc/2551-normalize-branch-name-resume

Conversation

@KC1706

@KC1706 KC1706 commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Fixes #2551.

Problem

entire session resume <branch> compared and looked up branch names byte-for-byte, with no Unicode normalization. Git treats a precomposed (NFC, é U+00E9) and decomposed (NFD, e + U+0301) spelling of the same accented branch as one branch (core.precomposeUnicode), so git checkout finds it either way — but entire would report branch '<name>' not found locally or on origin when the supplied name's normalization differed from the on-disk ref. It bit cross-platform teams: a branch created on Linux (NFD) and synced couldn't be resumed on a macOS checkout (NFC), especially once refs were packed (git gc), where go-git matches packed-refs byte-exact.

Fix

  • ResolveLocalBranchName (git_operations.go): exact ref match wins; otherwise it scans local branches and matches normalization-insensitively (fold to NFC), returning the canonical on-disk ref name so the checkout and the downstream checkpoint lookup target the real branch. Works on both NFC (macOS) and NFD (Linux) checkouts.
  • branchNamesEquivalent: NFC-folded comparison with an ASCII fast path, used for the "already on this branch" check that previously failed even while standing on the branch.
  • switchToBranchForResume now returns the resolved canonical name and threads it through resumeFromCurrentBranch (and the two trail resume callers), so the rest of resume uses the real ref name.

golang.org/x/text was already an (indirect) dependency; this promotes it to direct.

Testing

Scope

Deliberately scoped to the resume path from #2551. Other branch-name comparison sites (e.g. dispatch --all-branches) share the same underlying gap and could reuse these helpers in a follow-up; happy to do that separately if you'd prefer.

…entireio#2551)

`entire session resume <branch>` compared and looked up branch names
byte-exact, so a name differing from the on-disk ref only by Unicode
normalization (NFC vs NFD) was reported "not found" even though git treats
the two spellings as the same branch (core.precomposeUnicode) and checks it
out fine. This bit cross-platform teams: a branch created on Linux (NFD) and
synced could not be resumed on a macOS checkout (NFC), especially once refs
were packed (go-git matches packed-refs byte-exact).

Add ResolveLocalBranchName, which resolves a supplied name to the canonical
on-disk ref by folding to NFC when an exact lookup misses, plus
branchNamesEquivalent for the "already on this branch" fast path. Thread the
resolved name through switchToBranchForResume so the checkout and the
downstream checkpoint lookup target the real branch. Regression tests cover
the NFC/NFD packed-ref case.

Fixes entireio#2551
@KC1706
KC1706 force-pushed the kc/2551-normalize-branch-name-resume branch from 8db6168 to de2cf6d Compare October 9, 2026 17:20
@KC1706

KC1706 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main — the earlier conflicts (trail_cmd.go, go.mod) are resolved and it's now a single clean commit. Verified locally: build, the NFC/NFD regression tests, and mise run lint all pass. Ready whenever you have a moment.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

entire session resume <branch> reports "branch not found" for a Unicode-equivalent (NFC vs NFD) branch name that git resolves fine

1 participant