Security·terminal · desktop·no license file
git-gates
Blocks commit, push and merge unless your last message asks; vets commit messages.

git-gates stops Claude Code from running git commit, git push or a PR/MR merge unless your most recent typed message asks for it. It also refuses commits whose subject is not Conventional Commits or whose last line does not name the issue they are about, sends the rest to a Haiku review of the body, checks that a PR or MR description keeps to a fixed block structure, refuses a push to a branch that already landed, and asks Sonnet whether a pushed series leaves the project working at every commit. It is for people who let Claude work on a repo for long stretches and want the shipping moments, and only those, to stay in their hands. Every commit that clears the consent and format checks costs one Haiku call; a push of two or more new commits costs one Sonnet call.
What it does
- Consent. A
git commitorgit pushneeds one of commit, push, ship, deploy, merge, pr, mr, tag or release as a word in your latest message. A merge needs the word merge. Nothing older counts, a message generated by another plugin does not count, and a background task reporting back does not replace your last message. - Protected branches. With a
.claude/push-policy.jsonin the repo listingprotected_branches, a push to one of them needs your message to name that branch next to a shipping verb. Otherwise the denial tells Claude to push the feature branch and open a PR instead. - Commit grants. If your message asks for several commits (“3 commits”, “commit after each task”, “keep committing for the rest of the session”), the first authorized commit opens a grant for the rest: the number you gave, 10 for the whole session, 5 per task. Claude can also open one with a
granttool the mod registers, but only after an authorizing message in the last 30. Grants never cover push. - Commit messages. The subject must match Conventional Commits (
feat,fix,chore,docs,refactor,test,perf,build,ci,style,revert, with optional scope). Body lines that pre-answer a reviewer (“nothing else changed”, “no impact on X”) are refused. Then Haiku judges whether the body earns its place. - Issue references. When your messages or the branch name mention an issue or ticket (
#87,BLK-23, an issue URL, a branch likeperf/mobile-lcp-89), the commit message must end with it. A bare#87counts only in a repo with a remote; issues you typed bind only commits in the session’s repo and its worktrees. - Landed branch. A push is refused when the branch’s pushed head already sits in a protected branch and your message names no new MR, because the push would recreate a merged branch and leave the commit outside any MR. Saying “new MR for the follow-up” steps the check aside.
- Every commit works. A push of 2 to 15 commits that no remote has yet goes to Sonnet with each commit’s subject, files and trimmed diff, and is refused if one commit removes something a later one still uses, or uses something a later one adds. Skipped when your message says the order is fine.
- PR and MR descriptions.
gh pr,glab mrand direct API calls that set a description must use### Labelheadings from a fixed list (Symptom, Cause, Measured, Scope, Constraint, Cost, Verified, Remaining), start every line at column 0, and carry no line crediting Claude, Anthropic or a model.
Install
Needs Claude Code 2.1.287 or later. The author declares no minimum version. The plugin lives in the git-gates folder of the author’s marketplace repository, next to three unrelated mods about docs, comments and scripts.
claude plugin marketplace add bahaospanov/claude-mods
claude plugin install git-gates@bahaospanov
Nothing to run: from the next session every Bash call is checked. Claude Code logs a note when a grant is used or opened, and shows a status line while Haiku reviews a commit message.
How it works
Three events. prompt.submit keeps the last 30 prompts in memory and marks whether each came from you (composer, bridge or SDK) or from a plugin. After a reload or resume that list is empty, so the mod falls back to the session transcript and counts every user message as yours, skipping task notifications and system reminders. session.start registers the grant tool. tool.call on Bash does the rest, in five passes.
Pass one detects the verb with regular expressions: an API merge URL, gh pr merge or glab mr merge is a merge; otherwise quoted strings are stripped and the command is searched for git push or git commit, so a command that only mentions git push inside a string passes. It works out which repo the command runs in from its cd steps and -C flags. It then reads your latest message and applies the rules above. When it blocks, it denies the call with a reason addressed to Claude: stop, state what is ready, wait for the user. It never rewrites the command and never asks you anything itself. If the check throws, the call is denied too.
Pass two parses the commit message out of -m '...', a heredoc on -F -, or a -F file it reads from disk, and applies the format and issue-reference rules. --no-edit commits are skipped.
Pass three is the Haiku call. For any command that runs git commit and got this far, the mod sends the full Bash command (message included), the tool description and the working directory as JSON to claude-haiku-4-5-20251001 through $.model.complete, with a system prompt asking for a one-object JSON verdict. Haiku is told to pass anything that is not an actual commit, to accept an empty body when the subject already says why, and to refuse bodies that restate the diff, list the files, narrate how the change was made or exist because the author had things to say. A refusal denies the commit with Haiku’s reason, under 50 words. A reply that is not valid JSON is logged and the commit goes through. The diff itself is not sent. The author gives no token figure; count on one short Haiku request per commit attempt, with a fixed prompt of about 300 words plus your command.
Pass four is for pushes. The mod runs git merge-base --is-ancestor to see whether the pushed head already sits in a protected branch, and lists the commits the remote lacks. A series of 2 to 15 goes to claude-sonnet-5-5, which the author picked over Haiku after it raised false alarms on a real series: each commit’s subject, file list and diff, cut to 6,000 characters (3,000 for deleted content), with the question whether any commit breaks the project before a later one repairs it. Unlike the commit review, this call does send diffs. Pushes with --all, --mirror, --tags or --delete are not checked this way.
Pass five handles descriptions: it finds the text in the command, in a file the command points to ($HOME is the only variable expanded), in an inline JSON body, or in a body that jq builds. A description piped in as JSON (--data @-) cannot be read and is denied with a suggestion to send a file instead.
Nothing is written to disk. The mod runs git for the repo root, the current branch, the ancestry check and the series’ diffs, reads .claude/push-policy.json and message files, and makes no network call beyond the two model reviews. Prompts and the grant live in memory for the session.
Limitations
- Only Bash commands are checked. A commit made through another tool or an MCP server is not gated.
- The keyword test is literal: the word pr, mr, tag or release anywhere in your latest message authorizes a commit or push. The Haiku review sees the command, not the diff; the Sonnet review of a pushed series does see the diffs.
- A grant expires after two hours by default, eight at most, and 20 uses at most.
- Merge and grant phrasing is also recognised in Russian; other languages need the English keywords.
- Version 0.7.0. The README calls the whole marketplace early access with an API that changes between releases. No minimum Claude Code version is declared, and the repository has no license file.
Similar Claude Mods
secret-redactor
Swaps secrets, emails and IPs for placeholders before the model sees them.
env
Claude manages your .env keys and asks you for values it never gets to see.
toolgate
Asks TypeSafe's Jev seven risk questions per tool call, then allows, asks or denies.
pii-guard
Reversible Taiwanese PII redaction for tool results, prompts and writes, all on loopback.
Popular Claude Mods
The whole directory →claude-latex
TeX math, TikZ diagrams and LaTeX blocks typeset in Claude's replies, in the desktop app.
cc-stretch
Replies arrive short; click a phrase and it grows in place, click « to fold it back.
blast-radius
Shows what rm -rf or a force push would change and waits for Proceed or Cancel.
fast-jev-compaction
Compaction that drops stale tool calls instead of summarizing; the rest stays verbatim.



