Skip to content

docs(worktree): correct three specs the selector refactor left stale - #3786

Merged
max-sixty merged 2 commits into
mainfrom
worktree-path-not-found-error
Aug 9, 2026
Merged

docs(worktree): correct three specs the selector refactor left stale#3786
max-sixty merged 2 commits into
mainfrom
worktree-path-not-found-error

Conversation

@max-sixty

Copy link
Copy Markdown
Owner

Three specs in #3785's selector refactor describe mechanisms that change removed or altered. Comment-only; no behavior change.

Each is wrong in a way a reader would act on rather than merely notice:

worktree_is_unusable closed with "false for a path git has no registration for". The !path.exists() early return makes that untrue as a claim about the return value — such a path answers true when it is simply gone. The sentence was only ever about the prunable lookup, so it now says so, and records that no caller reaches the combination (all three take their path out of the listing).

normalize_selector named three call sites, two of which no longer call it, and spent a paragraph explaining the string-comparison design the refactor deleted — documenting a removed mechanism as current, which is the worst of the three. It now names its one home and says what made a single home possible.

ResolvedTarget::selector credited only a rewrite with taking the path arm off, missing --create, which takes it off without rewriting anything.

The first was raised on #3785 after I had worked its other threads, so it never got a reply there. The other two came from re-reading the neighbouring specs while fixing it.

Why these were worth a change rather than a note

A spec that describes a deleted mechanism is worse than no spec: normalize_selector's explained why each assembly of the resolution ladder had to normalize for itself, which was true before Selector carried "may this token name a path?" as a fact rather than a string comparison. A reader adding a fourth entry point would have followed it and re-introduced the per-site normalization the refactor removed.

This was written by Claude Code on behalf of max-sixty

Each describes a mechanism the refactor changed, and each is wrong in a way a
reader would act on rather than merely notice.

`worktree_is_unusable` closed with "`false` for a path git has no registration
for". The `!path.exists()` early return makes that untrue as a claim about the
return value — such a path answers `true` when it is simply gone. The sentence
was only ever about the `prunable` lookup, so it says so, and records that no
caller reaches the combination.

`normalize_selector` named three call sites, two of which no longer call it,
and spent a paragraph explaining the string-comparison design the refactor
deleted — documenting a removed mechanism as current. It now names its one
home and says what made the single home possible.

`ResolvedTarget::selector` credited only a rewrite with taking the path arm
off, missing `--create`, which takes it off without rewriting anything.

@worktrunk-bot worktrunk-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The worktree_is_unusable and ResolvedTarget::selector rewrites both check out against the code — three callers for the former, all taking their path out of the listing (usable_worktree_for_branch, plan_switch via resolve_selector, recover::hint_for_repo), and branch_only() under --create for the latter.

One claim in the normalize_selector replacement overstates in the same shape the PR is fixing. "which every worktree selector reaches before resolution" isn't structurally true: resolve_switch_target returns out of the pr:/mr: arm before it ever calls expand_selector, so resolve_pr_target/resolve_remote_ref hand resolve_selector a Selector::rewritten_to(...) that never passed through normalization — as does resolve_target_selector(None), which wraps the cached default branch. That's correct behaviour (there's no typed token there to normalize), but a reader adding a fifth construction site would take the sentence as a guarantee the type doesn't give them, which is the failure mode the PR body names.

The same sentence's "That one home" also sits awkwardly one clause after naming two application sites; the suggestion folds both.

Comment thread src/git/repository/mod.rs Outdated
"every worktree selector reaches `expand_selector`" was itself the shape this
change is fixing. `resolve_switch_target` returns out of its `pr:`/`mr:` arm
first, and `resolve_target_selector(None)` wraps the cached default branch, so
both hand back a `Selector::rewritten_to` that never passed through
normalization. Correct behaviour — neither was a spelling anyone typed — but a
reader adding a construction site would have read the sentence as a guarantee
the type does not give.
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.

2 participants