Usa PreToolUse Hooks para interceptar comandos git en Bash y bloquear commits directos a main, formatos incorrectos y operaciones peligrosas.
Claude Code tiene permiso para ejecutar git commit, git push y git checkout directamente. La mayoría de las veces es conveniente, pero también significa que podría hacer commits directamente en main, escribir mensajes con formato arbitrario o hacer force push cuando no debería. Los Hooks pueden interceptar estas operaciones antes de que ocurran.
Todas las operaciones git en Claude Code se ejecutan a través de la herramienta Bash. El punto de interceptación es "matcher": "Bash" en PreToolUse.
#!/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 "No se permiten commits directos en $current_branch. Cambia a una rama feature primero." >&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 "Formato de mensaje de commit incorrecto." >&2
echo "Formato requerido: <type>(<scope>): <description>" >&2
echo "Ejemplo: feat(auth): add OAuth login" >&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 "Operación peligrosa bloqueada. Añade # ALLOW: <motivo> al final del comando para continuar." >&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 "Actualmente en $current_branch — commits y pushes directos bloqueados. Cambia a una rama feature." >&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 "Formato de mensaje incorrecto. Formato: <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 "Operación peligrosa bloqueada. Añade # ALLOW: <motivo> para continuar." >&2
exit 2
fi
fi
La gestión de flujos de trabajo git con Hooks se basa en: PreToolUse + matcher Bash + detección de comandos git. Tres reglas prioritarias: bloquear commits en main, validar formato de mensajes, interceptar force push y reset --hard.