Skip to content

fix(switch): resolve symlinked paths to existing worktrees - #2466

Merged
max-sixty merged 3 commits into
mainfrom
fix/issue-2460
Apr 29, 2026
Merged

max-sixty merged 3 commits into
mainfrom
fix/issue-2460

Conversation

@worktrunk-bot

Copy link
Copy Markdown
Collaborator

Problem

wt switch /path/to/symlink failed with No branch named ... when the target was a symlink resolving to an existing worktree, while wt switch /path/to/real-worktree succeeded.

The path-based fallback for existing worktrees (Repository::worktree_at_path) compared paths via lexical normalization (normalize_path::NormalizePath::normalize) only — symlink-equivalent spellings never matched.

Solution

Move paths_match / canonicalize_with_parents from src/commands/worktree/resolve.rs to worktrunk::path so they're reachable from the library crate, and switch worktree_at_path to use the symlink-aware comparison. The original location used the helper to detect path-mismatch warnings; the same logic now powers worktree identity.

Testing

  • New unit test worktree_at_path_resolves_symlinked_path in src/git/repository/tests.rs reproduces the bug — fails on main, passes after the fix.
  • New integration test test_switch_worktree_by_symlinked_path in tests/integration_tests/switch.rs covers the end-to-end wt switch <symlink> path.
  • Full lib test suite (1064 tests) and existing switch/remove/relocate integration suites all pass.

Closes #2460 — automated triage

@worktrunk-bot worktrunk-bot left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

One small visibility nit inline. The fix itself is right — canonicalizing both sides via canonicalize_with_parents resolves the symlink-blindness in worktree_at_path, and the worktree_at_path_resolves_symlinked_path unit test directly reproduces the bug from #2460.

Comment thread src/path.rs Resolved
@max-sixty

Copy link
Copy Markdown
Owner

@worktrunk-bot fix conflicts

worktrunk-bot and others added 3 commits April 29, 2026 19:09
`worktree_at_path` compared paths via lexical normalization, so a
symlink whose target was a worktree did not match — causing
`wt switch /tmp/link-to-worktree` to fail with `No branch named ...`.

Move `paths_match` / `canonicalize_with_parents` from
`commands/worktree/resolve.rs` into `worktrunk::path` and switch
`worktree_at_path` to the symlink-aware comparison.

Closes #2460

Co-Authored-By: Claude <noreply@anthropic.com>
It's only used by paths_match (same module) and tests via super::,
matching the original visibility before the move from resolve.rs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Collapse the two early returns into a single tuple-matched fallback and add
a test that exercises the degenerate path. Codecov flagged both branches as
uncovered; consolidating them lets the empty-path test reach the only fallback.

Co-Authored-By: Claude <noreply@anthropic.com>
@max-sixty
max-sixty merged commit a8f1d49 into main Apr 29, 2026
24 checks passed
@max-sixty
max-sixty deleted the fix/issue-2460 branch April 29, 2026 19:42
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.

wt switch fails to resolve existing worktrees through symlink paths

2 participants