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.
This commit is contained in:
teknium1 2026-07-01 05:21:20 -07:00 committed by Teknium
parent 9ed7252a98
commit 5d613a5638
2 changed files with 28 additions and 2 deletions

View file

@ -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"]

View file

@ -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"
)