Skip to content

feat(wsl): default a new Windows-drive project under a WSL default to Git for Windows (D1c-5) - #33122

Merged
nwparker merged 2 commits into
mainfrom
nwparker/wsl-d1c-5-new-drive-project-default
Oct 29, 2026
Merged

nwparker merged 2 commits into
mainfrom
nwparker/wsl-d1c-5-new-drive-project-default

Conversation

@nwparker

@nwparker nwparker commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​133 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​133
Prod 2 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​113 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​113

ELI5

When someone whose default runtime is WSL adds a project that lives on a Windows drive (C:\…), Orca runs that project's Git through WSL today. That is about 300 times slower than Git for Windows and misses edits made from Windows. After this PR, such a brand-new project starts out using Git for Windows, and its terminals and agents still run in WSL. It matches what the "Git" setting from #33090 / #33097 switches an existing project to.

What Changed

  • Before: a new C:\ project under a global WSL default inherits WSL for everything, Git included.
  • After: the project saves the same setting the conversion writes, { kind: 'wsl', distro: <the global default's distro>, git: 'windows-host' }. Terminals, agents, accounts and hooks still run in that distro. Git, and where new worktrees go, move to Windows.
  • Mechanism: src/main/wsl/wsl-drive-project-new-default.ts, called from the store's addRepo. Every add path ends there: add, create, clone, nested import, the runtime RPC and paired clients. It writes the default only when all of these hold:
    • Windows, with the internal WSL hosts gate open (the conversion is gated the same way);
    • a local git project (not a folder project) whose path is on a Windows drive;
    • the new project has no runtime setting of its own;
    • the global default is WSL with a named distro;
    • no linked worktree was made by WSL Git. Those links are Linux paths that Git for Windows can't read. feat(wsl): run Git for Windows for a WSL project on a Windows drive (D1c-2) #33090's preflight refuses them for the same reason. The links are read from .git/worktrees/*/gitdir. A checkout whose .git is a file (a linked worktree or a submodule) counts as unknown and keeps today's behaviour.

Why

  • Owner decision: repos on a Windows drive use Windows Git, keeping WSL terminals. Existing projects convert through feat(wsl): run Git for Windows for a WSL project on a Windows drive (D1c-2) #33090's checked flow. Only brand-new projects get the default.
  • Why pin the distro, not inherit. This is the same shape feat(wsl): run Git for Windows for a WSL project on a Windows drive (D1c-2) #33090's conversion saves. Without the pin, a later change of the global default could quietly move the project's Git back to WSL. The alternative was a new "inherit, but Windows Git" setting. It would need new resolution rules and a new settings UI state, and older peers would read it as plain inherit.
  • Why in addRepo and not each add path. There are about ten add paths. One hook covers all of them, plus future ones. The check it runs is a few small file reads, and only on Windows when the gate is open.
  • Compatibility. This uses no new field. An older build reads the saved setting as a plain WSL project, the same as for a converted project.

Linked Issue

Part of the WSL re-write, step D1c, decision (b) (risk rows R36, R6). Stacked on #33143 (the top of D1c), so that branch holds every D1c PR.

Visual Proof

N/A: no UI change. The project's settings show #33097's existing "Orca runs Git on Windows" row.

Testing

  • Automated tests: src/main/wsl/wsl-drive-project-new-default.test.ts covers:
    • the default itself;
    • each case where it is skipped: off Windows, Windows default, no distro, inside a distro, folder project, another host, WSL-made worktrees, unreadable links;
    • an existing preference is kept;
    • the closed gate;
    • link reading from a real temp checkout.
  • pnpm test src/main/persistence and pnpm tc:node pass locally.
  • Manual on Windows: not run (no Windows box assigned to this work).

Review

Self-reviewed.

Agent skill upstream boundary

  • Not applicable.

Notes

  • Flag-off: no change. addRepo now calls applyNewWindowsDriveProjectDefault, whose first check returns false while the gate is closed (wsl-drive-project-new-default.ts): no filesystem read, no project change, no extra save. Even with the gate open it skips SSH, folder workspaces, macOS and Linux.
  • SSH: remote projects are skipped (local only).
  • Folder workspaces: skipped; they run no Git.
  • Mobile and paired clients: the default is applied by the desktop that owns the project.

Status

@nwparker
nwparker marked this pull request as ready for review October 24, 2026 11:03
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-2-windows-git branch from 4744e59 to ae05cd2 Compare October 25, 2026 02:00
@nwparker
nwparker requested a review from brennanb2025 as a October 25, 2026 02:00
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from 7850743 to c70135b Compare October 25, 2026 02:03
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-2-windows-git branch from ae05cd2 to 2f43ad5 Compare October 25, 2026 02:29
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from c70135b to dd94f12 Compare October 25, 2026 02:32
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-2-windows-git branch from 2f43ad5 to 7a5ca94 Compare October 25, 2026 04:34
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from dd94f12 to 417b78b Compare October 25, 2026 04:35
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-2-windows-git branch from 7a5ca94 to 73563e1 Compare October 25, 2026 06:39
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from 417b78b to f19bde1 Compare October 25, 2026 06:40
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-2-windows-git branch from 73563e1 to bd03615 Compare October 25, 2026 08:30
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from f19bde1 to 9bc7249 Compare October 25, 2026 08:30
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-2-windows-git branch from bd03615 to 5f403b6 Compare October 25, 2026 09:48
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from 9bc7249 to f077845 Compare October 25, 2026 09:48
@nwparker
nwparker changed the base branch from nwparker/wsl-d1c-2-windows-git to nwparker/wsl-d1c-4d-unc-conversion-ui October 25, 2026 09:48
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from 6c14210 to 7166c56 Compare October 25, 2026 10:22
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from f077845 to f7337f6 Compare October 25, 2026 10:22
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from 7166c56 to 9a2b332 Compare October 25, 2026 11:10
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from f7337f6 to 0b3bfd6 Compare October 25, 2026 11:11
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from 9a2b332 to 244abe6 Compare October 25, 2026 12:00
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from 0b3bfd6 to a7136bc Compare October 25, 2026 12:00
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from 244abe6 to b36bf0a Compare October 25, 2026 12:36
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from a7136bc to f1da001 Compare October 25, 2026 12:36
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from b36bf0a to 0e8e459 Compare October 25, 2026 13:03
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from f1da001 to b59c2e9 Compare October 25, 2026 13:03
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from 0e8e459 to 363e860 Compare October 25, 2026 13:16
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from b59c2e9 to 71ac31c Compare October 25, 2026 13:17
@OrcaWin
OrcaWin force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from dce3e79 to 30b18bf Compare October 28, 2026 10:48
@OrcaWin
OrcaWin force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from ab1f214 to 9b42484 Compare October 28, 2026 11:30
@OrcaWin
OrcaWin force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from 30b18bf to fa3fa88 Compare October 28, 2026 11:31
@OrcaWin
OrcaWin force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from 9b42484 to 75aa19f Compare October 28, 2026 12:05
@OrcaWin
OrcaWin force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from fa3fa88 to 4e271a5 Compare October 28, 2026 12:05
@OrcaWin
OrcaWin force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from 75aa19f to a58d1f0 Compare October 28, 2026 20:57
@OrcaWin
OrcaWin force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from 4e271a5 to 17acf4a Compare October 28, 2026 20:57
@greptile-apps

greptile-apps Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 2/5

[Medium impact] The change affects setup for eligible new Windows-drive projects.

The PR is not ready to merge because all three previously reported failures remain.

Findings

  1. P1 Existing projects switch Git unexpectedly ▶
  2. P1 Unread links allow incompatible Git ▶
  3. P1 Missing Windows Git breaks projects ▶

Summary

Gives eligible Windows-drive projects Windows Git while keeping terminals and agents in the chosen WSL distro.

  • New Windows-drive projects use Windows Git and keep their WSL runtime.

Reviews (7) · Last reviewed commit: "fix(wsl): judge a new project's worktree..." · Reviewed by Greptile

Comment on lines +68 to +69
const project = state.projects.find((entry) => entry.sourceRepoIds.includes(repo.id))
if (!project || project.localWindowsRuntimePreference) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Existing projects switch Git unexpectedly

Adding another checkout of an existing project can silently switch that project's Git to Windows. addRepo merges checkouts with the same remote into one project before this helper runs. An existing project with no saved runtime choice passes this check, so adding a clean second checkout changes Git for the first checkout too, without checking its WSL-authored worktrees. Those worktrees can become unusable in Orca.

Capture whether the project existed before registration and apply this default only to a genuinely new project.

Knowledge Base Used: Desktop persistence and lifecycle

Comment on lines +98 to +103
return names.flatMap((name) => {
try {
return [readFileSync(join(root, name, 'gitdir'), 'utf8').trim()]
} catch {
return []
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Unread links allow incompatible Git

If reading worktrees or one of its gitdir files fails, this function returns an empty or incomplete list. The caller treats that as safe and saves git: 'windows-host', even when an unread link belongs to WSL Git. Windows Git cannot follow that link, so the linked worktree becomes unusable even after the read error clears.

Return [] only when the worktrees directory is absent. Return null for other directory errors or any failed link read so the project keeps its current behavior.

Knowledge Base Used:

@OrcaWin
OrcaWin force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from a58d1f0 to a30bcc8 Compare October 28, 2026 22:47
@OrcaWin
OrcaWin force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from 17acf4a to 167b601 Compare October 28, 2026 22:47
@OrcaWin
OrcaWin force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from 4288890 to 6cfca04 Compare October 29, 2026 01:16
@OrcaWin
OrcaWin force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from 167b601 to 600a856 Compare October 29, 2026 01:16
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from 6cfca04 to 881d451 Compare October 29, 2026 02:05
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from 600a856 to 663495b Compare October 29, 2026 02:06
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from 881d451 to 17b6f70 Compare October 29, 2026 02:33
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from 663495b to a919a01 Compare October 29, 2026 02:33
Comment on lines +49 to +50
// Pinned like a converted project, so a later global change can't silently switch its Git.
return { kind: 'wsl', distro: globalDefault.distro, git: 'windows-host' }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Missing Windows Git breaks projects

If a Windows user has Git installed only in WSL, they can still add an existing checkout because registration accepts a valid .git marker when Git cannot run. This helper then saves git: 'windows-host' without checking that Windows Git exists. Git actions that previously worked through WSL now fail.

Check that Windows Git can run before saving this default. If it cannot, leave the project inheriting its runtime.

@nwparker
nwparker force-pushed the nwparker/wsl-d1c-4d-unc-conversion-ui branch from 17b6f70 to 1c20978 Compare October 29, 2026 06:48
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from a919a01 to 1cb41e1 Compare October 29, 2026 06:56
nwparker and others added 2 commits October 29, 2026 00:13
… test, so a //wsl.localhost link counts as Windows Git's

Co-Authored-By: Claude <noreply@anthropic.com>
@nwparker
nwparker force-pushed the nwparker/wsl-d1c-5-new-drive-project-default branch from 1cb41e1 to 549afa7 Compare October 29, 2026 07:15
@nwparker
nwparker changed the base branch from nwparker/wsl-d1c-4d-unc-conversion-ui to main October 29, 2026 07:15
@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Walkthrough

The change adds Windows drive-project runtime preference selection and worktree-link reading. It applies a selected WSL preference to a project only when the WSL host gate is open and the project has no local preference. Repository addition schedules a save when the preference is written. Tests cover eligibility conditions, existing preferences, the host gate, and worktree-link states.

Priority: Normal

Merge Risk: Moderate · up to 549af

New Windows-drive projects on a WSL-default setup can be pinned to Windows Git in cases the feature is meant to skip: when the project already holds other repos, or when worktree link files cannot be read. This could cause worktree operations to fail or behave unexpectedly for affected users. Restrict the default to single-repo projects and treat unreadable worktree metadata as unknown before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: applying a WSL-related default for new Windows-drive projects. The issue identifier is relevant.
Description check Passed The description is detailed and covers the user-facing change, mechanism, rationale, scope, compatibility, testing, and platform limitations. It provides N/A visual proof and documents that manual Win…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description is detailed and covers the user-facing change, mechanism, rationale, scope, compatibility, testing, and platform limitations. It provides N/A visual proof and documents that manual Windows testing was not performed. The Linked Issue section references #33143 but does not provide the template's explicit Fixes line or a direct issue link.

Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 4 functions across 3 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2


Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 82401549-a288-4f00-89f5-35dce3d5a835
Commits

Reviewing files that changed from the base of the PR and between 084c765 and 549afa7.

Files selected for processing: 3
  • src/main/persistence/loading-store/repo-lifecycle-operations.ts
  • src/main/wsl/wsl-drive-project-new-default.test.ts
  • src/main/wsl/wsl-drive-project-new-default.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

Comment on lines +68 to +69
const project = state.projects.find((entry) => entry.sourceRepoIds.includes(repo.id))
if (!project || project.localWindowsRuntimePreference) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Major · Data Integrity & Integration · Heavy lift

Do not change an existing project based on one added repo.

A project can contain multiple sourceRepoIds. If addRepo adds a Windows-drive repo to an existing project with no local preference, this search selects that project and pins Windows Git for all its repos. The selector checks only the newly added repo, so the other repos may not meet the Windows-drive or worktree-link conditions. Apply this default only to a newly created, single-repo project, or validate every repo in the project before writing the project-wide preference. (raw.githubusercontent.com)

Comment on lines +95 to +96
} catch {
return []

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Major · Data Integrity & Integration · Quick win

Treat unreadable worktree metadata as unknown.

If listing .git/worktrees fails for a reason other than ENOENT, returning [] tells the selector that there are no links. If one gitdir read fails, flatMap silently removes that link. Either case can hide a WSL-authored link and persist a Windows Git preference that the worktree preflight would reject. Return null for these failures; reserve [] for a missing worktrees directory. (raw.githubusercontent.com)

Also applies to: 100-102

Source: Learnings

@nwparker
nwparker merged commit 71f030f into main Oct 29, 2026
68 of 93 checks passed
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