Skip to content

fix(terminal): force Git for Windows bash + convert native CWD for bash cd - #330

Merged
hashbender merged 1 commit into
mainfrom
mirror/pr-56384
Jul 1, 2026
Merged

fix(terminal): force Git for Windows bash + convert native CWD for bash cd#330
hashbender merged 1 commit into
mainfrom
mirror/pr-56384

Conversation

@hashbender

Copy link
Copy Markdown
Owner

Summary

Windows terminal commands launched from PowerShell/cmd now work instead of failing with exit 126 — fixed at the root by forcing one canonical bash, not by translating around whichever shell PATH happened to resolve.

Root cause was two-layered:

  1. _find_bash() called shutil.which("bash") before checking Git-for-Windows install paths. On any machine with WSL installed, PATH returns C:\Windows\System32\bash.exe (the WSL shim), so Hermes silently ran WSL bash instead of Git Bash — a different drive-mount dialect (/mnt/c vs /c).
  2. Native cwd (C:\Users\x) was embedded verbatim into bash cd, which no bash dialect can resolve → cd: C:\Users\...: No such file or directoryexit 126 on the first command of every session.

Changes

  • tools/environments/local.py (@Icather): reorder _find_bash() so explicit Git-for-Windows paths win over shutil.which("bash"). Git Bash always beats the WSL shim → one canonical MSYS shell, one path dialect. Fixes [Bug]: _find_bash() resolves to WSL bash before checking system Git-for-Windows paths on Native Windows NousResearch/hermes-agent#47837.
  • tools/environments/local.py (@LeonSGP43): add _windows_to_msys_path() (C:\Users\x/c/Users/x) + a LocalEnvironment._quote_cwd_for_cd override that applies it. No-op on non-Windows.
  • tools/environments/base.py (follow-up): route the init_session snapshot bootstrap cd through _quote_cwd_for_cd too — the override previously only reached _wrap_command, so the bootstrap cd still leaked the raw Windows path and pwd -P captured the login shell's dir instead of terminal.cwd. Also add -- for hyphen-safety to match _wrap_command.
  • Tests: cover _windows_to_msys_path, the _wrap_command cd conversion, and the init_session bootstrap conversion.

Why force one shell instead of dialect-detecting

Several competing PRs proposed detecting whether the resolved bash is Git Bash or WSL and emitting /c/ vs /mnt/c/ accordingly. That translates around the symptom. The design intent (_find_bash's own error: "requires Git for Windows") is one canonical shell. Fixing the resolution order makes the whole /mnt/c dialect-mismatch bug class impossible rather than handling it downstream.

Validation

Before After
_find_bash() w/ WSL on PATH + Git for Windows returns WSL shim returns Git for Windows bash
cd in _wrap_command on Windows cd C:\Users\x → exit 126 cd -- /c/Users/x
cd in init_session bootstrap cd C:\Users\x (fails silently) cd -- /c/Users/x
Non-Windows unchanged unchanged (no-op)

E2E tested with real imports against a simulated Windows env (fake Git-for-Windows + WSL shim on PATH); both layers verified. Targeted suite: 17/17 green.

Supersedes NousResearch#50596, NousResearch#42105 (same MSYS conversion, less complete), NousResearch#53475 (wrong premise — WSL is not always the shell), NousResearch#54321 (dialect detection unnecessary once the shell is forced; also bundled an unrelated coding_context change), NousResearch#13397 (mistitled — never converted paths), NousResearch#47920 (duplicate of the _find_bash reorder).

Fixes NousResearch#50594, NousResearch#35459, NousResearch#47837.

Infographic

infographic


Mirror-of: NousResearch#56384
NousResearch#56384

@tenki-reviewer

tenki-reviewer Bot commented Jul 1, 2026

Copy link
Copy Markdown

Review Complete
No issues found!

Risk: 🟢 Low (12/100) — no findings · 125 LOC across 3 files


PR adds new Windows MSYS2/Git Bash terminal backend test coverage and refactors local environment classes for clarity. No defects found — all 6 scanner passes returned clean.

Files Reviewed (3 files)
tests/tools/test_local_env_windows_msys.py
tools/environments/base.py
tools/environments/local.py

@hashbender
hashbender merged commit bab74bd into main Jul 1, 2026
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

1 participant