Skip to content

fix: gate remote branch deletion pushed as an empty refspec - #130

Open
Arakiss wants to merge 3 commits into
mainfrom
fix/git-push-delete-refspec-gate
Open

fix: gate remote branch deletion pushed as an empty refspec#130
Arakiss wants to merge 3 commits into
mainfrom
fix/git-push-delete-refspec-gate

Conversation

@Arakiss

@Arakiss Arakiss commented Jul 25, 2026

Copy link
Copy Markdown
Owner

git push origin :main deletes the remote branch. Today that command is allowed outright, while an ordinary git push origin main requires a signed picto.

Cause. bash-git-push captures the whole refspec into ref, so :main emits git.push:refs/heads/:main. No branch gate matches that string and the call falls through to allow.

Fix. A mapper for the empty-source refspec that emits the destination branch, so the existing branch gates apply, plus a dedicated git.push.delete capability. The new gate-remote-branch-delete rule covers every branch, not only protected ones: deleting a colleague's feature branch destroys shared work even where pushing to it is allowed.

Mappers accumulate rather than short-circuit (mapper.rs:154), so adding one does not alter existing rules.

Verified against a copy of a real policy tree, comparing the shipped binary with the built one:

command before after
git push origin :main allow ask_picto
git push origin :dev allow ask_picto
git push origin :feat/algo allow ask_picto
git push origin main ask_picto ask_picto
git push --force origin main ask_picto ask_picto
git push origin feat/x allow allow

Two regression fixtures added to examples/policy-fixtures.yaml, which CI already runs. cargo fmt --check clean, cargo clippy --all-targets -- -D warnings clean, 155 tests pass.

Arakiss added 3 commits July 16, 2026 21:11
git push origin :main deletes the remote branch. The bash-git-push mapper
captured the whole refspec, so that command emitted git.push:refs/heads/:main,
which matches no branch gate. The result was that deleting main was allowed
outright while an ordinary push to the same branch required a picto.

Adds a mapper for the empty-source refspec that emits the destination branch,
so existing branch gates apply, plus a git.push.delete capability. The new
gate-remote-branch-delete rule covers every branch rather than only protected
ones: deleting a colleague's feature branch destroys shared work even where
pushing to it is allowed.

Verified against a copy of a real policy tree: git push origin :main, :dev and
:feat/algo all move from allow to ask_picto, while git push origin main,
git push --force origin main and git push origin feat/x keep their previous
decisions. Two regression fixtures cover the deletion cases.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant