# How to Add Custom Git Command Patterns to the Guardrails Blocklist in Claude Code

> Easily add custom git command patterns to your Claude Code guardrails blocklist. Edit the DANGEROUS_PATTERNS array in the block-dangerous-git.sh script to enhance your repository's security.

- Repository: [Matt Pocock/skills](https://github.com/mattpocock/skills)
- Tags: how-to-guide
- Published: 2026-04-04

---

**To add custom git command patterns to the guardrails blocklist, edit the `DANGEROUS_PATTERNS` array in the installed [`block-dangerous-git.sh`](https://github.com/mattpocock/skills/blob/main/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`](https://github.com/mattpocock/skills/blob/main/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:

```bash
<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:

```bash
~/.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:

```bash
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 \.` matches `git 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:

```bash
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:

```bash
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:

```bash

# 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:

```bash

# 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:

```bash
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.sh`](https://github.com/mattpocock/skills/blob/main/.claude/hooks/block-dangerous-git.sh) in your project root or home directory.
- **Array Name**: Extend `DANGEROUS_PATTERNS` with 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 +x` after any edit.
- **Validation**: Test with `echo '{"tool_input":{"command":"your-command"}}' | ./block-dangerous-git.sh` to 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`](https://github.com/mattpocock/skills/blob/main/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`](https://github.com/mattpocock/skills/blob/main/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.