Free

Mengelola alur kerja git dengan Hooks: membuat Claude juga mengikuti aturan

Gunakan PreToolUse Hooks untuk mencegat perintah git di Bash dan memblokir commit langsung ke main, format pesan yang salah, dan operasi berbahaya.


Claude Code memiliki izin untuk menjalankan git commit, git push, dan git checkout secara langsung. Biasanya ini nyaman, tapi juga berarti Claude bisa commit ke main, menulis pesan commit sembarangan, atau force push di waktu yang salah. Hooks mencegat operasi ini sebelum terjadi.


Pendekatan: PreToolUse untuk Mencegat Perintah Git di Bash

Semua operasi git di Claude Code dijalankan melalui tool Bash. Titik pencegatan adalah "matcher": "Bash" di PreToolUse.


Aturan 1: Blokir Commit Langsung ke Main

#!/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 "Commit langsung ke $current_branch tidak diizinkan. Pindah ke branch feature terlebih dahulu." >&2
  exit 2
fi

Aturan 2: Paksa Format Pesan Commit

#!/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 "Format pesan commit tidak sesuai." >&2
  echo "Format: <type>(<scope>): <description>" >&2
  exit 2
fi

Aturan 3: Blokir Operasi Berbahaya

#!/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 "Operasi berbahaya diblokir. Tambahkan # ALLOW: <alasan> untuk melanjutkan." >&2
    exit 2
  fi
fi

Konfigurasi Lengkap

.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 "Saat ini di $current_branch — commit dan push langsung diblokir. Pindah ke branch 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 "Format pesan commit salah. 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 "Operasi berbahaya diblokir. Tambahkan # ALLOW: <alasan> untuk melanjutkan." >&2
    exit 2
  fi
fi

Ringkasan

Mengelola alur kerja git dengan Hooks: PreToolUse + matcher Bash + deteksi perintah git. Tiga aturan utama: blokir commit ke main, validasi format pesan, cegat force push dan reset --hard.