Skip to content

fix(shell): discover native Git Bash on Windows instead of WSL - #243

Merged
Uking-xxx merged 2 commits into
mainfrom
fix/windows-native-bash-discovery
Oct 12, 2026
Merged

Uking-xxx merged 2 commits into
mainfrom
fix/windows-native-bash-discovery

Conversation

@Uking-xxx

@Uking-xxx Uking-xxx commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Fixes #136. If Git for Windows is installed in a non-default directory, the installer only adds <Git>\cmd to PATH. Shell discovery then falls through to where bash.exe, which returns C:\Windows\System32\bash.exe first. That is the WSL launcher, so commands silently run inside WSL without the Windows Node/npm toolchain. Separately, background commands under Git Bash exit 1 with an empty log when the log file descriptor is handed to MSYS.

Summary

This combines the contributor's fork PRs (ZXJC-niusile#1 and #2) with one review fix.

  • Discovery order on Windows: Program Files → Program Files (x86) → %LOCALAPPDATA%\Programs\Git → Git installation next to each git.exe on PATH (cmd, bin, mingw32/64/bin) → native bash.exe on PATH. Symlinks are resolved, and where.exe is no longer used. PowerShell lookup uses the same PATH scan.
  • WSL is never auto-selected. An explicit shellPath pointing at the WSL launcher still works, and still uses the stdin command transport.
  • Git Bash child PATH: Git's bin and usr/bin are prepended for the Git Bash child process only. The system PATH is unchanged.
  • Background commands on Windows: stdout/stderr are piped into a log stream owned by the parent instead of passing the fd through. Unix is unchanged.
  • Config value commands: !command config values (resolve-config-value.ts) now get the same Git Bash child PATH as run_command.
  • Review fix: candidates are generated lazily, and lookup stops at the first valid Bash. A standard install now returns after a few file checks and never scans PATH. Previously PATH was scanned twice on every run_command and every permission check.

Compatibility

On native Windows with only WSL bash.exe available, Step now fails with clear instructions instead of silently switching to the Linux toolchain. Users who want WSL can set shellPath explicitly or run Step inside WSL.

Validation

  • test/shell-discovery.test.ts: custom, portable and mingw Git roots; known install locations; Git shims; symlinks; quoted and relative PATH entries; WSL rejection under a custom SystemRoot; explicit WSL transport; Git Bash child PATH; Unix fallbacks; no PATH scan when a known install exists. The two lazy-lookup tests fail against the previous eager version.
  • test/step-tool-profile.test.ts: background logs capture both stdout and stderr.
  • pnpm run check passes, and the shell/bash/background/powershell vitest subset passes (447 tests).
  • Run on macOS with platform mocks. The contributor reported 30 targeted tests passing on real Windows and a full test.sh passing on Ubuntu 24.04 (WSL2) for the fork changes. No Windows run yet for the lazy-lookup change.

Out of scope

Two Windows baseline issues found by the contributor are not fixed here: execFileSync("npm", ...) fails with ENOENT, and config migration extracts filenames from backslash paths incorrectly.

Co-authored-by: @ZXJC-niusile

xuyunfang and others added 2 commits October 12, 2026 11:07
On Windows, a Git for Windows install in a non-default directory only puts
<Git>\cmd on PATH, so shell discovery fell through to `where bash.exe` and
picked C:\Windows\System32\bash.exe, silently running commands inside WSL.

- Look for Git Bash in Program Files, Program Files (x86),
  %LOCALAPPDATA%\Programs\Git, then relative to each git.exe on PATH, then
  native bash.exe on PATH. Resolve symlinks and drop the where.exe dependency.
- Never select the WSL launcher automatically; an explicit shellPath to it
  keeps its stdin command transport.
- Add the Git installation's bin and usr/bin to the Git Bash child PATH only.
- On Windows, pipe background command output into the log file instead of
  handing the file descriptor to MSYS, which exited 1 with an empty log.
- Generate candidates lazily so a standard install returns without scanning
  PATH on every command or permission check.

Fixes #136

Co-authored-by: ZXJC-niusile <2632590648@qq.com>
Config values written as `!command` were run with a direct spawnSync on the
resolved shell, bypassing spawnShellChild, so on Windows they did not get the
Git installation's bin and usr/bin on PATH. Export withGitBashPath and apply
it there too so these commands see the same tools as run_command.
@Uking-xxx
Uking-xxx merged commit b4ce5a0 into main Oct 12, 2026
1 of 3 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.

Windows 自定义 Git 安装目录下误选 WSL Bash(fork 已修复,申请贡献上游)

1 participant