How to Add Custom Git Command Patterns to the Guardrails Blocklist in Claude Code
To add custom git command patterns to the guardrails blocklist, edit the DANGEROUS_PATTERNS array in the installed block-dangerous-git.sh hook script and append your POSIX extended regular expressions.
The Git Guardrails skill from the mattpocock/skills repository protects against destructive git operations by intercepting commands before Claude executes them. When you need to block additional workflows—such as interactive rebases or force merges—you customize the blocklist by modifying the Bash hook that Claude invokes during its PreToolUse lifecycle.
How the Git Guardrails Blocklist Works
The guardrail mechanism centers on scripts/block-dangerous-git.sh, a Bash hook registered in Claude's settings. According to the mattpocock/skills source code, this script contains a hard-coded array named DANGEROUS_PATTERNS that stores POSIX extended regular expressions. When Claude prepares to execute a git command, it passes the tool input as JSON to this hook, which extracts the tool_input.command field and iterates through the array. If grep -qE finds a match, the script exits with code 2 and emits a BLOCKED message, preventing execution.
The default patterns block high-risk operations like git push --force, git reset --hard, and git clean -fd. Because the script evaluates patterns using standard regex, you can craft precise rules that match substrings, flags, or entire command structures.
Locating the Hook Script
Before editing the blocklist, locate the active installation of the hook. The skill supports two installation scopes, and the file path determines which projects inherit your custom patterns.
Project-Scoped Installation
For repository-specific guardrails, the hook resides within the project root:
<project-root>/.claude/hooks/block-dangerous-git.sh
Changes here affect only the current repository, making this ideal for team-specific safety requirements that travel with version control.
Global Installation
For system-wide protection across all Claude Code sessions, the hook lives in your home directory:
~/.claude/hooks/block-dangerous-git.sh
Modifications here apply to every project unless overridden by a local project hook.
Adding Custom Patterns to the Blocklist
Once you locate the script, extend the DANGEROUS_PATTERNS array with new regex entries. Each entry must follow POSIX extended regular expression syntax, escaping special characters like periods or brackets where necessary.
Editing the DANGEROUS_PATTERNS Array
Open the script in any text editor and locate the array definition. Append your custom patterns inside the parentheses:
DANGEROUS_PATTERNS=(
"git push"
"git reset --hard"
"git clean -fd"
"git clean -f"
"git branch -D"
"git checkout \."
"git restore \."
"push --force"
"reset --hard"
# ── Custom additions ──────────────────────────────────────
"git revert" # block plain revert
"git rebase -i" # block interactive rebases
"git merge --no-ff" # block force-merged merges
)
Key syntax rules:
- Escape literal dots with
\.(e.g.,git checkout \.matchesgit checkout .) - Quote entries to preserve spaces and special characters
- The script uses
grep -qE, so extended regex features like|(alternation) are supported
After saving, ensure the script remains executable:
chmod +x <path-to-hook>/block-dangerous-git.sh
Testing Your Custom Patterns
Validate your regex before relying on it in production. The hook expects JSON on stdin mimicking Claude's tool invocation format:
echo '{"tool_input":{"command":"git revert HEAD~1"}}' | <path-to-hook>/block-dangerous-git.sh
Expected output for a blocked command:
BLOCKED: 'git revert HEAD~1' matches dangerous pattern 'git revert'.
Exit code: 2
If the command passes through (exit code 0), refine the pattern until the test blocks as intended.
Practical Examples
Blocking Specific Commands (git revert, git rebase -i)
To prevent accidental history rewriting or reverts, add explicit command patterns:
# Edit the installed script
sed -i '/^DANGEROUS_PATTERNS=(/a \ \ "git cherry-pick"' \
~/.claude/hooks/block-dangerous-git.sh
# Verify blocking works
echo '{"tool_input":{"command":"git cherry-pick abc123"}}' \
| ~/.claude/hooks/block-dangerous-git.sh
# → BLOCKED message, exit code 2
Refining Pattern Precision
Replace broad patterns with stricter matches to avoid over-blocking. For example, block only force-pushes instead of all pushes:
# Replace the generic "push --force" with a stricter pattern
sed -i 's/"push --force"/"git push --force"/' \
.claude/hooks/block-dangerous-git.sh
# Test normal push passes through
echo '{"tool_input":{"command":"git push origin main"}}' \
| .claude/hooks/block-dangerous-git.sh # passes (exit 0)
# Test force push gets blocked
echo '{"tool_input":{"command":"git push --force origin main"}}' \
| .claude/hooks/block-dangerous-git.sh # BLOCKED (exit 2)
Bulk Adding Multiple Patterns
For extensive customization, append a batch update to the end of the script:
cat >> .claude/hooks/block-dangerous-git.sh <<'EOF'
# Custom Guardrails – additional dangerous git commands
DANGEROUS_PATTERNS+=(
"git revert"
"git rebase -i"
"git merge --no-ff"
)
EOF
chmod +x .claude/hooks/block-dangerous-git.sh
This technique preserves the original array while appending project-specific rules, making future diffs readable.
Summary
- Hook Location: Edit
.claude/hooks/block-dangerous-git.shin your project root or home directory. - Array Name: Extend
DANGEROUS_PATTERNSwith quoted POSIX extended regular expressions. - Regex Syntax: Escape special characters (e.g.,
\.for literal dots) and test patterns using JSON input on stdin. - Execution Rights: Maintain executable permissions with
chmod +xafter any edit. - Validation: Test with
echo '{"tool_input":{"command":"your-command"}}' | ./block-dangerous-git.shto confirm exit code 2 and BLOCKED output.
Frequently Asked Questions
Where is the blocklist stored?
The blocklist resides in the DANGEROUS_PATTERNS array inside block-dangerous-git.sh. For project-specific rules, edit <project-root>/.claude/hooks/block-dangerous-git.sh. For global rules affecting all Claude Code sessions, edit ~/.claude/hooks/block-dangerous-git.sh.
What regex syntax should I use for patterns?
Use POSIX extended regular expressions (ERE) as supported by grep -qE. This includes character classes, alternation with |, and quantifiers. Remember to escape literal dots, asterisks, and brackets with backslashes when you intend to match the literal character rather than the regex metacharacter.
Do I need to restart Claude Code after editing the hook?
No. The hook is invoked fresh before each tool use, so changes to block-dangerous-git.sh take effect immediately on the next git command. Ensure the file remains executable after editing, or Claude will fail to run the guardrail check.
How do I verify a pattern will block the intended command?
Test the hook manually by piping a JSON payload that mimics Claude's tool input: echo '{"tool_input":{"command":"git your-command"}}' | /path/to/block-dangerous-git.sh. A successful block returns exit code 2 and prints a BLOCKED message naming the matched pattern. Adjust the regex until the test behaves as expected before committing the change.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →