From 5d613a5638f8ea02b6b9d82fd8573c3d73724358 Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Wed, 1 Jul 2026 05:21:20 -0700 Subject: [PATCH] fix(terminal): route init_session bootstrap cd through Windows path conversion The Windows _quote_cwd_for_cd override only reached _wrap_command; the snapshot bootstrap cd in init_session still used a bare shlex.quote(), so on Windows the bootstrap cd failed and pwd -P captured the login shell's dir instead of terminal.cwd. Route it through _quote_cwd_for_cd too, and add -- for hyphen-safety to match _wrap_command. --- tests/tools/test_local_env_windows_msys.py | 21 +++++++++++++++++++++ tools/environments/base.py | 9 +++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/tests/tools/test_local_env_windows_msys.py b/tests/tools/test_local_env_windows_msys.py index 777935b17ec..1b05aaaeace 100644 --- a/tests/tools/test_local_env_windows_msys.py +++ b/tests/tools/test_local_env_windows_msys.py @@ -246,3 +246,24 @@ class TestWrapCommandWindowsNativeCwd: assert "builtin cd -- /c/Users/liush || exit 126" in wrapped assert r"builtin cd -- C:\Users\liush || exit 126" not in wrapped + + def test_init_session_bootstrap_converts_native_cwd_for_cd(self, monkeypatch): + """The snapshot bootstrap ``cd`` must also use the Git-Bash path form, + not just ``_wrap_command`` — otherwise ``pwd -P`` captures the login + shell's directory instead of ``terminal.cwd`` on Windows.""" + monkeypatch.setattr(local_mod, "_IS_WINDOWS", True) + + captured = {} + + def fake_run_bash(self, cmd_string, *, login=False, timeout=120, stdin_data=None): + captured["script"] = cmd_string + raise RuntimeError("stop after capturing bootstrap") + + monkeypatch.setattr(LocalEnvironment, "_run_bash", fake_run_bash) + + # init_session swallows the exception and falls back; we only need the + # captured bootstrap script to assert the cd target was converted. + LocalEnvironment(cwd=r"C:\Users\liush", timeout=10) + + assert "builtin cd -- /c/Users/liush 2>/dev/null || true" in captured["script"] + assert r"C:\Users\liush" not in captured["script"] diff --git a/tools/environments/base.py b/tools/environments/base.py index 67107690f1b..ef5b683aad2 100644 --- a/tools/environments/base.py +++ b/tools/environments/base.py @@ -361,7 +361,12 @@ class BaseEnvironment(ABC): # Restore configured cwd after login shell profile scripts, which may # change the working directory (e.g. bashrc `cd ~`). Without this, # pwd -P captures the profile's directory, not terminal.cwd. - _quoted_cwd = shlex.quote(self.cwd) + # Route through ``_quote_cwd_for_cd`` (not a bare ``shlex.quote``) so + # the Windows subclass override converts a native ``C:\Users\x`` cwd to + # the Git-Bash ``/c/Users/x`` form the bootstrap ``cd`` can resolve. + # Without this the snapshot bootstrap ``cd`` below fails on Windows and + # ``pwd -P`` captures the login shell's directory, not ``terminal.cwd``. + _quoted_cwd = self._quote_cwd_for_cd(self.cwd) # Quote the snapshot / cwd-file paths so Git Bash on Windows handles # ``C:/Users/...``-shaped paths without glob-splitting the colon or # tripping on drive letters. On POSIX this is a no-op (no colons / @@ -413,7 +418,7 @@ class BaseEnvironment(ABC): # Publish atomically only if assembly succeeded; otherwise drop the # partial temp rather than leave it to be sourced or orphaned. f"mv -f {_snap_tmp} {_quoted_snap} || rm -f {_snap_tmp}\n" - f"builtin cd {_quoted_cwd} 2>/dev/null || true\n" + f"builtin cd -- {_quoted_cwd} 2>/dev/null || true\n" f"pwd -P > {_quoted_cwd_file} 2>/dev/null || true\n" f"printf '\\n{self._cwd_marker}%s{self._cwd_marker}\\n' \"$(pwd -P)\"\n" )