An agent with shell access will eventually try git push --force or git reset --hard when it gets confused. You don't need to watch every command. A small PreToolUse hook can stop the dangerous ones before they run.
The hook
Save this as .claude/hooks/block-risky-git.sh and make it executable (chmod +x):
#!/usr/bin/env bash
# Reads the tool call as JSON on stdin; exit code 2 blocks it.
cmd=$(jq -r '.tool_input.command // ""')
if echo "$cmd" | grep -Eq 'git (push .*(--force|-f)|reset --hard|clean -fd|branch -D|checkout -- \.)'; then
echo "Blocked: '$cmd' can destroy work. Ask the user to run it themselves." >&2
exit 2
fi
exit 0
Then register it in .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": ".claude/hooks/block-risky-git.sh" }]
}
]
}
}
What happens
When Claude tries one of those commands, the hook exits with code 2. The command never runs, and the message on stderr goes back to Claude, so it explains the situation to you instead of retrying blindly.
Tips
- Keep the pattern list short and specific. Blocking all of
git pushjust trains you to turn the hook off. - Commit the hook so everyone on the repo gets the same guardrail.
- Pair it with a Bash allow-list so ordinary commands don't prompt you every time.
I ship this hook alongside a Bash allow-list, .env deny rules, a /review command, and a short CLAUDE.md in Vildanden Agent Config. The free sample is enough to try the pattern today.
Top comments (0)