Skip to content

Fix worktrees failing to open on WSL: translate POSIX worktree paths to UNC#63

Open
flix-wg wants to merge 1 commit into
aleixrodriala:mainfrom
flix-wg:fix/worktree-path-translation
Open

Fix worktrees failing to open on WSL: translate POSIX worktree paths to UNC#63
flix-wg wants to merge 1 commit into
aleixrodriala:mainfrom
flix-wg:fix/worktree-path-translation

Conversation

@flix-wg

@flix-wg flix-wg commented Jul 10, 2026

Copy link
Copy Markdown

Fixes #62.

Problem

Worktrees on a WSL repo fail to open (\home\... invalid). git returns POSIX worktree paths; upstream parseWorktreePorcelainOutput runs them through Path.normalize, which on Windows only flips separators (/home\home) without adding a volume, leaving a rootless path Windows can't resolve. The repo path works because it comes from the folder picker (correct UNC); only git-discovered worktree paths are left untranslated. Full analysis in #62.

Change

New patch patches/07-worktree-path-translation.patch, following the numbered git apply convention. Two hunks, entirely within the fork's own code:

app/src/lib/wsl.ts — add two exported helpers:

  • linuxPathToWSL(distro, linuxPath) — inverse of parseWSLPath; builds \\wsl.localhost\<distro>\....
  • isRootlessPosixPath(p) — true for a POSIX-rooted path, including the backslash-flipped form Path.normalize yields on Windows (\home\..., a single leading backslash, not a \\ UNC path). Drive-letter and UNC paths return false.

app/src/lib/git/worktree.ts — in listWorktrees (not the parser): the parser only receives stdout and has no repo context, whereas listWorktrees has the Repository.path → distro. After parsing, if the repo is a WSL path, lift rootless worktree entry paths to UNC.

Design guards

  • Distro derived from the parent repo's UNC path via parseWSLPath — never hardcoded (Ubuntu, etc.).
  • Translate only when the repo is WSL (isWSLPath) and the entry path is rootless. Native Windows paths pass untouched.
  • Guards on the post-Path.normalize form: on Windows the path is already \home\..., so a naive startsWith('/') check would miss it — isRootlessPosixPath handles both /home and \home.
  • Assumes the worktree lives on the same distro as its parent (true for the normal case and for .claude/worktrees/). Cross-distro worktrees would get the wrong prefix — documented known edge, not handled.
  • Scoped to worktrees; submodule paths (submodule.ts) likely share the bug — flagged as a separate follow-up in Worktrees fail to open: worktree paths not translated POSIX→UNC (\home\... invalid) #62, not touched here.

Verification

  • Patches 01–07 apply cleanly with git apply against a pristine desktop/desktop@release-3.6.2 checkout (current latest upstream release-* tag). Hunks use minimal, stable context anchors.
  • No upstream automated test suite for this path → manual E2E (I cannot run the Windows build here; leaving final E2E to a WSL+Windows environment):
    1. In WSL, create a repo with ≥1 worktree (git worktree add).
    2. Add the parent repo in the built app.
    3. Confirm each worktree opens, shows the correct branch, and diffs load.
    4. Before/after screenshots.

Risk

Patch fragility — CI applies patches with strict git apply against each new release-* every 6h. The worktree.ts hunk is anchored on the stable listWorktrees shape; re-diff if upstream restructures it. Re-verify against the live tag at merge time (do not assume 3.6.2 if a newer tag has shipped).

🤖 Generated with Claude Code

Worktrees on a WSL repo fail to open in Desktop with:
  The worktree path '\home\user\...\.claude\worktrees\<name>'
  does not appear to be a valid Git repository.

git runs inside the distro and returns POSIX worktree paths. Upstream
parseWorktreePorcelainOutput runs each through Path.normalize, which on
Windows only flips separators (/home -> \home) without adding a volume,
so Windows cannot resolve the path. The repository path itself works
because the user enters it via the folder picker (correct UNC); only the
git-discovered worktree paths are left untranslated.

Fix, entirely inside the WSL fork's own code:
- wsl.ts: add linuxPathToWSL (inverse of parseWSLPath) and
  isRootlessPosixPath (detects a POSIX-rooted path, incl. the
  backslash-flipped form Path.normalize yields on Windows).
- worktree.ts: in listWorktrees (which has the Repository/UNC path, unlike
  the context-free parser), lift rootless entry paths to
  \\wsl.localhost\<distro>\... The distro is derived from the parent repo's
  UNC path, never hardcoded. Native Windows paths pass through untouched.

Verified: patches 01-07 apply cleanly with git apply against a pristine
desktop/desktop@release-3.6.2 checkout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@flix-wg

flix-wg commented Jul 10, 2026

Copy link
Copy Markdown
Author

Still needs testing :)

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.

Worktrees fail to open: worktree paths not translated POSIX→UNC (\home\... invalid)

1 participant