Last week, a Claude Code session ran rm -rf target/ across my projects to free disk space. It deleted the release binary my autonomous loop depends on. I was offline for hours.
That was files. Git is worse. A git push --force can rewrite shared history. A git reset --hard throws away uncommitted work with no undo. A git clean -fd deletes untracked files permanently.
Claude Code is good at git. But "good at git" and "never makes a destructive mistake" are different things.
git-safe: a PreToolUse hook
git-safe intercepts Bash commands before they run and blocks destructive git operations. It suggests safer alternatives instead of just saying no.
What it blocks:
| Blocked command | Suggested alternative |
|---|---|
git push --force |
git push --force-with-lease |
git reset --hard |
git stash |
git checkout -- . |
git stash |
git clean -f |
git clean -n (dry run) |
git branch -D |
git branch -d (safe delete) |
git stash drop |
(warns about permanent loss) |
git stash clear |
(warns about permanent loss) |
git reflog expire |
(warns about safety net removal) |
What it allows:
Everything else. Regular commits, pushes, pulls, merges, rebases, checkouts. It only catches the operations where a mistake means lost work.
Install
One command:
curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/git-safe/install.sh | bash
Or install it alongside other hooks (read-once, file-guard):
curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- git-safe
How it works
git-safe is a Claude Code PreToolUse hook. When Claude calls the Bash tool, the hook checks the command against its block list. If it matches, the hook returns a JSON error with a suggested alternative. Claude sees the suggestion and uses the safer command instead.
The hook script is ~60 lines of bash. No dependencies, no background processes, no network calls.
Allowlist
Sometimes you actually need force-push (rebasing a feature branch, for example). Create a .git-safe file in your project root:
push --force
reset --hard
Each line is a pattern to allow. git-safe checks for this file and skips matching rules.
The real problem this solves
AI coding assistants are fast. Fast enough to run git reset --hard before you can read what they're doing. The damage from a destructive git command isn't always recoverable, especially if reflog has been expired or if you're working with uncommitted changes.
git-safe adds a 5ms check before each Bash call. You won't notice the latency. You will notice the first time it catches a force-push you didn't mean to approve.
Source
github.com/Bande-a-Bonnot/Boucle-framework/tree/main/tools/git-safe
45 tests. MIT license. Works on macOS and Linux.
Top comments (0)