closes #3455 · git-validator worktree false-DENY
main)Every commit and push from a linked worktree was denied as "Cannot commit or push directly to 'main' branch", including commands that named a feature branch as their destination.
The guard's own comments explain why. Resolution order is
git -C <path>, then session-state shell_cwd — and
that second path is dead:
// git-validator.ts:190 // "in 1763 recorded sessions no state file ever gained a shell_cwd (#3411) // ... `git push` from a worktree was therefore judged against the project dir"
So without an explicit -C, branch resolution falls back to the primary
checkout, which is on main. Unknown cwd resolved to DENY.
If every git push in a command names its destination and none is
protected, the command cannot touch a protected remote ref regardless of which
directory it runs in. No cwd knowledge required.
Scope note worth stating: this deliberately covers
git commit && git push origin <feature> too. Restricting it to
push-only commands would have fixed neither real-world report. A commit in that
chain is local-only; the protected remote ref is provably untouched, which is what
"push directly to main" guards.
The parser is all-or-nothing on purpose. One unresolvable push must not be vouched for by a sibling that happens to name a feature branch:
git push origin feat/x && git push // second push resolves through upstream: unknowable // -> extractPushDestinations returns null -> falls through to the old path
A bare git push can still reach main via upstream config, so it
is never treated as proof of anything.
| Command | Before | After |
|---|
This is part A of #3455. The deeper defect stands: when cwd is genuinely unresolvable
and the command names no destination (a bare git push, or a plain
git commit), the guard still resolves ambiguity to DENY. Part B is to make
that case ASK, or to fix shell_cwd (#3411) so the second resolution path
stops being dead.