[BUG] Windows/Git Bash: git <ref>:<dot-path> arguments silently rewritten, so a mangled command looks like a missing file

Status Open
Maintainer reply None cached
Activity 0 comments · opened Sep 3, 2026

Summary

On Windows with Git Bash, the Bash tool silently rewrites git arguments of the form <ref>:<path> when the ref contains a slash and the path starts with a dot. The rewritten argument reaches git as a Windows path list, and git fails to resolve it.

The failure is indistinguishable from "that file does not exist in that ref", which is what makes it costly: git show <branch>:.<something> is the natural way to check whether a file is present on a branch, and a mangled argument and a genuinely absent file produce the same practical outcome — nothing.

Repro

In any git repo on Windows, via the Bash tool (Git Bash):

git show 'origin/main:.github/workflows/ci.yml'

Actual:

fatal: ambiguous argument 'origin\main;.github\workflows\ci.yml': unknown revision or path not in the working tree.

Note both transformations: / became \, and the : became ;. MSYS has treated the argument as a colon-separated PATH list and converted it to Windows form.

Which shapes are affected

Measured on Git for Windows, same repo, same command shape:

| Argument | Result |
|---|---|
| origin/main:home/CLAUDE.md | ok |
| origin/main:.githooks/post-merge | mangled |
| origin/feat/some-branch:home/CLAUDE.md | ok |
| origin/feat/some-branch:.githooks/post-merge | mangled |
| HEAD:.githooks/post-merge | ok |
| HEAD:home/CLAUDE.md | ok |

So the trigger is specifically: a ref containing a slash, plus a path beginning with a dot. A HEAD: ref is safe, and a non-dotted path is safe. That narrowness is part of the problem — the same command works for most paths, so the behaviour reads as "this file is missing" rather than "this invocation is broken".

Dot-directories are common in exactly the files an agent tends to inspect: .github/, .gitea/, .claude/, .specify/, .githooks/, .vscode/.

Why it matters for an agent specifically

An agent reasons from command output. Here the output is a plausible negative, so the wrong conclusion is reached confidently and then acted on. In our case a git show <branch>:.specify/memory/constitution.md returned nothing, that was read as "the file is not on this branch", and three repositories were reported as having adopted a config file when none of them had. Several follow-up checks appeared to confirm it — but every one of them went through the same mangling, so the agreement was one failure repeated, not corroboration.

Workarounds (both verified on every failing case above)

MSYS_NO_PATHCONV=1 MSYS2_ARG_CONV_EXCL='*' git show 'origin/main:.github/workflows/ci.yml'

or run the command through PowerShell, which has no MSYS layer.

Suggested fix

Any of these would remove the class of error:

  1. Set MSYS_NO_PATHCONV=1 / MSYS2_ARG_CONV_EXCL='*' in the environment the Bash tool creates on Windows, at least for git invocations.
  2. Detect the <ref>:<dot-path> shape in a Bash command on Windows and either apply the guard automatically or warn.
  3. Surface the mangling: if git reports ambiguous argument and the quoted argument differs from what was sent, say so. Right now the difference between the sent and received argument is visible in the error text but easy to read past.

Option 1 seems least surprising — the current behaviour converts arguments the caller did not intend as paths.

Environment

  • Windows 11 Pro 26100
  • Git for Windows (Git Bash), used as the Bash tool shell
  • Reproduced consistently; not intermittent

View original on GitHub ↗