* fix(git): run WSL git reads without a shell
WSL-routed git ran through the distro user's interactive login shell for
one reason: to inherit their PATH. That shell also runs the distro's
rc/motd and writes it to the stdout callers parse, which is why #10917
reports a shell banner breaking GitHub source detection.
A shell-free route already existed (`--exec /usr/bin/env PATH=... git`,
added for status reads in #13207) but it was opt-in, and only
gitStatusReadOptionsForWorktree opted in. Every other read -- remote
get-url, config --get, log, show, rev-parse -- took the login shell on
every call, so the reported parse never benefited.
Classify reads at the resolver instead of at each caller. A read needs
nothing the login shell provides, so it takes the direct route without
the caller asking. Writes and network operations stay on the login
shell: they can depend on credential helpers and ssh-agent that the
user's profile sets up.
Subcommands that both read and write (config, remote, branch,
submodule) require an explicit read flag before they qualify, so
`config --get` goes direct while `config user.email x` does not.
`git show` blob reads stop forcing the login shell and go direct too.
The fence stays on that path: the login shell is still the fallback when
the environment probe is cold or rejected, and a banner there would
become file content.
Behavior note: the first WSL read per distro now also warms the
environment probe in the background, so a cold read spawns one extra
wsl.exe. Subsequent reads start no shell at all.
* fix(git): keep queried WSL remote reads on login shell
* style: format WSL runner test
* fix(git): match WSL read markers positionally
The conditional read markers were matched anywhere after the subcommand,
so a positional argument that happened to share a marker's name routed a
write shell-free: `worktree remove list` read as a listing, and
`submodule foreach status` as a status query -- the latter can run
arbitrary commands, including network ones.
Split the two kinds of marker apart. `config`/`branch` are flag-marked
and still match anywhere; `remote`/`worktree`/`submodule` are
action-marked and must match the first non-flag argument. The queried
`remote show` rule and the `symbolic-ref` arity rule are unchanged.
Neither case is reachable today -- Orca issues no `submodule foreach`,
and the worktree paths are its own CLI, not git argv -- but the loose
match was the shape of the defect, not those two instances.
* test(git): pin read routing behind global options
Writes hidden behind -c/-C/--git-dir must not reach the shell-free
route, and an unparsed global form must fall back to the login shell
rather than guess at the subcommand. Both directions fail safe.
---------
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>