Skip to content

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

Open

Description

@KC1706

What happened

Branch names with accented characters can be encoded two ways that look identical but are different bytes: precomposed (NFC, é = U+00E9) and decomposed (NFD, e + U+0301). Git treats them as the same branch — git checkout finds the branch either way (that's core.precomposeUnicode).

Entire doesn't. entire session resume <branch> compares and looks up the branch name byte-for-byte with no normalization, so if the name passed differs in normalization from the ref stored on disk, Entire reports:

branch 'feature/café' not found locally or on origin

...even though the branch exists and git checkout on the same name works. Resuming with the other spelling succeeds.

Entire is also internally inconsistent here: entire session info <id> --json prints the branch in its stored (NFD) form, but feeding that exact value back into entire session resume fails.

Where this bites

Cross-platform teams. Git on Linux does not precompose, so a branch created there keeps the NFD form; Entire stores that in the session state and syncs it. A teammate on macOS (where the local branch is NFC) then can't resume it by the synced name — and once the ref is packed (git gc) the NFD spelling no longer resolves via the filesystem either.

Root cause (current main, 59df1a1)

No Unicode normalization is applied to branch names anywhere. In the resume path:

  • cmd/entire/cli/resume.go — currentBranch == branchName is a byte-exact compare, so the "already on this branch" fast-path fails even while standing on the branch.
  • cmd/entire/cli/git_operations.go — GetCurrentBranch returns head.Name().Short() and BranchExistsLocally does repo.Reference(plumbing.NewBranchReferenceName(name), true), both byte-exact. go-git's packed-refs lookup is exact-byte, so the NFD spelling misses once refs are packed.

Steps to reproduce

Simulated on one macOS machine by toggling core.precomposeUnicode to mimic a Linux origin:

  1. git config core.precomposeUnicode false
  2. git checkout -b "$(printf 'feature/cafe\xcc\x81')" # NFD
  3. Run an agent session that makes a change + commit → Entire stores session state with branch in NFD.
  4. git config core.precomposeUnicode true; recreate/checkout the branch as NFC (printf 'feature/caf\xc3\xa9'); git pack-refs --all.
  5. Compare:
    • entire session resume "$(printf 'feature/cafe\xcc\x81')" → "branch not found locally or on origin"
    • entire session resume "$(printf 'feature/caf\xc3\xa9')" → resumes fine
    • git checkout "$(printf 'feature/cafe\xcc\x81')" → succeeds

Impact

A failed resume plus a misleading "not found" error for a branch that exists. Not data loss — the interactive picker recovers via its checkpoint-trailer fallback, and checkpoint list is reachability-based; it's the direct session resume <branch> path (and the session info --json → session resume round-trip) that breaks.

Suggested fix

Compare branch names normalization-insensitively (fold to NFC) and resolve a supplied name to the actual local ref before checkout — the same idea as the case-folding fix in #2403, applied to Unicode normalization. Happy to open a PR with a regression test (an NFC/NFD branch pair over a packed ref).

This is distinct from #2398, which is about git diff --cached --name-only quoting of non-ASCII file paths in commit-linking.

Activity

  1. KC1706 commented on Sep 21, 2026

    @KC1706
    ContributorAuthor

    @Soph @ashtom this issue contains pr #2552 ready for review .

  2. KC1706 commented on Oct 9, 2026

    @KC1706
    ContributorAuthor

    #2552, #2534 are ready for review
    @Soph @ashtom please review these prs and merge

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions