Problem
A locally-configured ask pattern intended to catch dangerous git argument-injection flags (`--upload-pack`, `--receive-pack`, `--exec-path`) was firing as a false positive on a completely benign command:
```
git -C ~/some/repo worktree list 2>&1 | grep verify
```
against a pattern shaped like:
```
git\s+(-c|b)+--exec-path|--upload-pack|--receive-pack
```
Root causes (two independent bugs)
- Case-fold collapses
-c/-C: `Pattern::builtin()` auto-wraps every built-in pattern in `(?i)`, so any pattern segment intended to distinguish `-c` (safe config override) from `-C` (safe "run git as if in this dir") loses that distinction unless explicitly wrapped in `(?-i:...)`.
- Unwrapped
| alternation: `A|B|C` inside a larger pattern is three fully independent, unanchored top-level alternatives — not "A, followed by (B or C)". So `--upload-pack` and `--receive-pack` matched anywhere in the command, without needing the intended `git` prefix at all.
Fix
Replaced the broken combined pattern with three independent, correctly-scoped built-in ask patterns in `builtin_ask()`:
- `git --upload-pack`: `\bgit\b.*--upload-pack\b`
- `git --receive-pack`: `\bgit\b.*--receive-pack\b`
- `git --exec-path`: `\bgit\b.*--exec-path\b`
None of these three flags need any `-c`/`-C` prefix scoping to be dangerous, so the fix sidesteps the case-fold trap entirely rather than patching around it.
Test plan
- Unit + e2e regression tests confirming the exact reported false positive (`git -C ... worktree list | grep verify`) now passes
- Unit + e2e regression test confirming `git -c user.name=... status` (lowercase, legitimate config override) also passes
- Unit + e2e tests confirming all three flags independently trigger `ask` when actually present
Problem
A locally-configured ask pattern intended to catch dangerous git argument-injection flags (`--upload-pack`, `--receive-pack`, `--exec-path`) was firing as a false positive on a completely benign command:
```
git -C ~/some/repo worktree list 2>&1 | grep verify
```
against a pattern shaped like:
```
git\s+(-c|b)+--exec-path|--upload-pack|--receive-pack
```
Root causes (two independent bugs)
-c/-C: `Pattern::builtin()` auto-wraps every built-in pattern in `(?i)`, so any pattern segment intended to distinguish `-c` (safe config override) from `-C` (safe "run git as if in this dir") loses that distinction unless explicitly wrapped in `(?-i:...)`.|alternation: `A|B|C` inside a larger pattern is three fully independent, unanchored top-level alternatives — not "A, followed by (B or C)". So `--upload-pack` and `--receive-pack` matched anywhere in the command, without needing the intended `git` prefix at all.Fix
Replaced the broken combined pattern with three independent, correctly-scoped built-in ask patterns in `builtin_ask()`:
None of these three flags need any `-c`/`-C` prefix scoping to be dangerous, so the fix sidesteps the case-fold trap entirely rather than patching around it.
Test plan