Mit PreToolUse Hooks git-Befehle in Bash abfangen — direkte Commits nach main, falsche Nachrichtenformate und gefährliche Operationen blockieren.
Claude Code hat die Berechtigung, git commit, git push und git checkout direkt auszuführen. Das ist meistens praktisch, kann aber dazu führen, dass direkt auf main committed, beliebige Commit-Messages geschrieben oder unerwünschte Force-Pushes durchgeführt werden. Hooks greifen vor diesen Operationen ein.
#!/bin/bash
input=$(cat); cmd=$(echo "$input" | jq -r '.tool_input.command')
echo "$cmd" | grep -qE '^git (commit|push)' || exit 0
current_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
if [[ "$current_branch" == "main" || "$current_branch" == "master" ]]; then
echo "Direkte Commits auf $current_branch sind nicht erlaubt. Wechseln Sie zuerst zu einem Feature-Branch." >&2; exit 2
fi
#!/bin/bash
input=$(cat); cmd=$(echo "$input" | jq -r '.tool_input.command')
echo "$cmd" | grep -qE '^git commit' || exit 0
msg=$(echo "$cmd" | grep -oP '(?<=-m )["\x27].*?["\x27]' | tr -d '"'"'" || true)
[[ -z "$msg" ]] && exit 0
if ! echo "$msg" | grep -qE '^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{3,}'; then
echo "Commit-Message-Format ist falsch. Format: <type>(<scope>): <description>" >&2; exit 2
fi
#!/bin/bash
input=$(cat); cmd=$(echo "$input" | jq -r '.tool_input.command')
if echo "$cmd" | grep -qE 'git push.*--force|git reset --hard|git push.*--delete'; then
if ! echo "$cmd" | grep -q '# ALLOW:'; then
echo "Gefährliche Operation blockiert. Fügen Sie # ALLOW: <Grund> hinzu, um fortzufahren." >&2; exit 2
fi
fi
.claude/hooks/git-guard.sh:
#!/bin/bash
set -e
input=$(cat); cmd=$(echo "$input" | jq -r '.tool_input.command // empty')
[[ -z "$cmd" ]] && exit 0
echo "$cmd" | grep -q '^git' || exit 0
current_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
if echo "$cmd" | grep -qE '^git (commit|push)'; then
if [[ "$current_branch" == "main" || "$current_branch" == "master" ]]; then
echo "Auf $current_branch — direkte Commits und Pushes blockiert. Wechseln Sie zum Feature-Branch." >&2; exit 2
fi
fi
if echo "$cmd" | grep -qE '^git commit.*-m'; then
msg=$(echo "$cmd" | grep -oP '(?<=-m )["\x27][^\x27"]*["\x27]' | tr -d '"'"'" || true)
if [[ -n "$msg" ]] && ! echo "$msg" | grep -qE '^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{3,}'; then
echo "Falsches Format. Format: <type>(<scope>): <description>" >&2; exit 2
fi
fi
if echo "$cmd" | grep -qE 'git push.*--force|git reset --hard|git push.*--delete'; then
if ! echo "$cmd" | grep -q '# ALLOW:'; then
echo "Gefährliche Operation blockiert. Fügen Sie # ALLOW: <Grund> hinzu." >&2; exit 2
fi
fi
PreToolUse + Bash-Matcher + git-Befehlserkennung. Drei wichtigste Regeln: Commits auf main blockieren, Message-Format validieren, Force Push und Reset --hard abfangen.