Free

إدارة سير عمل git باستخدام الخطّافات: جعل Claude يلتزم بالقواعد أيضاً

استخدم PreToolUse Hooks لاعتراض أوامر git في Bash ومنع الالتزام المباشر بـ main وتنسيق الرسائل الخاطئ والعمليات الخطيرة.


يملك Claude Code صلاحية تشغيل git commit وgit push وgit checkout مباشرةً. هذا مريح في الغالب، لكنه قد يؤدي إلى commit على main، أو كتابة رسائل بتنسيق عشوائي، أو force push في وقت خاطئ. تتدخل Hooks قبل وقوع هذه العمليات.


القاعدة 1: منع الـ commit المباشر على 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 المباشر على $current_branch. انتقل إلى فرع feature أولاً." >&2; exit 2
fi

القاعدة 2: إلزام تنسيق رسالة الـ 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 "تنسيق رسالة الـ commit غير صحيح. التنسيق: <type>(<scope>): <description>" >&2; exit 2
fi

القاعدة 3: منع العمليات الخطرة

#!/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 "عملية خطرة تم حجبها. أضف # ALLOW: <السبب> للمتابعة." >&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 "أنت على $current_branch — الـ commit والـ push المباشران محجوبان. انتقل إلى فرع 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 "تنسيق خاطئ. التنسيق: <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 "عملية خطرة محجوبة. أضف # ALLOW: <السبب> للمتابعة." >&2; exit 2
  fi
fi

الخلاصة

PreToolUse + matcher Bash + كشف أوامر git. ثلاث قواعد رئيسية: منع الـ commit على main، التحقق من تنسيق الرسائل، حجب force push وreset --hard.