Install/uninstall hooks that enforce git-town over raw git commands in Claude Code. Blocks forbidden git commands. TRIGGERS - enforce git-town, install hooks, git-town hooks, prevent raw git.
From git-town-workflownpx claudepluginhub terrylica/cc-skills --plugin git-town-workflowThis skill is limited to using the following tools:
references/evolution-log.mdSearches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides idea refinement into designs: explores context, asks questions one-by-one, proposes approaches, presents sections for approval, writes/review specs before coding.
This command installs Claude Code hooks that BLOCK forbidden raw git commands.
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
| Forbidden Command | Reason | Replacement |
|---|---|---|
git checkout -b | Creates untracked branches | git town hack |
git pull | Bypasses sync workflow | git town sync |
git merge | Manual merges break flow | git town sync |
git push origin main | Direct main push dangerous | git town sync |
git branch -d | Manual branch deletion | git town delete |
git rebase | Complex, use git-town | git town sync |
| Allowed Command | Reason |
|---|---|
git add | Staging files (git-town doesn't replace) |
git commit | Creating commits (git-town doesn't replace) |
git status | Viewing status (read-only) |
git log | Viewing history (read-only) |
git diff | Viewing changes (read-only) |
git stash | Stashing changes (utility) |
git remote | Remote management (setup only) |
git config | Configuration (setup only) |
The following hook will be added to ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/env bash -c 'CMD=\"$CLAUDE_TOOL_INPUT_command\"; case \"$CMD\" in \"git checkout -b\"*|\"git checkout -B\"*) echo \"BLOCKED: Use git town hack instead of git checkout -b\"; exit 1;; \"git pull\"*) echo \"BLOCKED: Use git town sync instead of git pull\"; exit 1;; \"git merge\"*) echo \"BLOCKED: Use git town sync or git town ship instead of git merge\"; exit 1;; \"git push origin main\"*|\"git push origin master\"*) echo \"BLOCKED: Use git town sync instead of pushing to main\"; exit 1;; \"git branch -d\"*|\"git branch -D\"*) echo \"BLOCKED: Use git town delete instead of git branch -d\"; exit 1;; \"git rebase\"*) echo \"BLOCKED: Use git town sync (rebase strategy) instead of git rebase\"; exit 1;; esac'"
}
]
}
]
}
}
/usr/bin/env bash -c 'cat ~/.claude/settings.json 2>/dev/null || echo "{}"'
AskUserQuestion with questions:
- question: "Install git-town enforcement hooks to block forbidden raw git commands?"
header: "Install Hooks"
options:
- label: "Yes, install hooks (Recommended)"
description: "Blocks: git checkout -b, git pull, git merge, git push main"
- label: "No, don't install"
description: "I want to use raw git commands freely"
- label: "Show what will be blocked"
description: "Display full list of blocked commands"
multiSelect: false
Read existing settings, merge hooks, write back:
/usr/bin/env bash << 'INSTALL_HOOK_EOF'
SETTINGS_FILE="$HOME/.claude/settings.json"
# Create file if doesn't exist
if [[ ! -f "$SETTINGS_FILE" ]]; then
echo '{}' > "$SETTINGS_FILE"
fi
# Read existing settings
EXISTING=$(cat "$SETTINGS_FILE")
# Define the new hook
NEW_HOOK='{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/env bash -c '\''CMD=\"$CLAUDE_TOOL_INPUT_command\"; case \"$CMD\" in \"git checkout -b\"*|\"git checkout -B\"*) echo \"BLOCKED: Use git town hack instead of git checkout -b\"; exit 1;; \"git pull\"*) echo \"BLOCKED: Use git town sync instead of git pull\"; exit 1;; \"git merge\"*) echo \"BLOCKED: Use git town sync or git town ship instead of git merge\"; exit 1;; \"git push origin main\"*|\"git push origin master\"*) echo \"BLOCKED: Use git town sync instead of pushing to main\"; exit 1;; \"git branch -d\"*|\"git branch -D\"*) echo \"BLOCKED: Use git town delete instead of git branch -d\"; exit 1;; \"git rebase\"*) echo \"BLOCKED: Use git town sync (rebase strategy) instead of git rebase\"; exit 1;; esac'\''"
}
]
}'
# Merge using jq
echo "$EXISTING" | jq --argjson hook "$NEW_HOOK" '
.hooks.PreToolUse = ((.hooks.PreToolUse // []) + [$hook] | unique_by(.matcher + (.hooks[0].command // "")))
' > "$SETTINGS_FILE.tmp" && mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE"
echo "✅ Hook installed successfully"
cat "$SETTINGS_FILE" | jq '.hooks'
INSTALL_HOOK_EOF
/usr/bin/env bash -c 'cat ~/.claude/settings.json | jq ".hooks.PreToolUse"'
AskUserQuestion with questions:
- question: "Remove git-town enforcement hooks?"
header: "Uninstall"
options:
- label: "Yes, remove hooks"
description: "Allow raw git commands again"
- label: "No, keep hooks"
description: "Keep enforcement active"
multiSelect: false
/usr/bin/env bash << 'UNINSTALL_HOOK_EOF'
SETTINGS_FILE="$HOME/.claude/settings.json"
if [[ ! -f "$SETTINGS_FILE" ]]; then
echo "No settings file found"
exit 0
fi
# Remove git-town enforcement hook
cat "$SETTINGS_FILE" | jq '
.hooks.PreToolUse = [.hooks.PreToolUse[]? | select(.matcher != "Bash" or (.hooks[0].command | contains("git town") | not))]
' > "$SETTINGS_FILE.tmp" && mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE"
echo "✅ Hook removed successfully"
UNINSTALL_HOOK_EOF
/usr/bin/env bash << 'STATUS_HOOK_EOF'
SETTINGS_FILE="$HOME/.claude/settings.json"
echo "=== GIT-TOWN ENFORCEMENT HOOK STATUS ==="
if [[ ! -f "$SETTINGS_FILE" ]]; then
echo "❌ No settings file found"
echo " Run: /git-town-workflow:hooks install"
exit 0
fi
# Check if hook exists
HOOK_EXISTS=$(cat "$SETTINGS_FILE" | jq '[.hooks.PreToolUse[]? | select(.hooks[0].command | contains("git town"))] | length')
if [[ "$HOOK_EXISTS" -gt 0 ]]; then
echo "✅ Git-town enforcement hook is ACTIVE"
echo ""
echo "Blocked commands:"
echo " - git checkout -b → use git town hack"
echo " - git pull → use git town sync"
echo " - git merge → use git town sync"
echo " - git push origin main → use git town sync"
echo " - git branch -d → use git town delete"
echo " - git rebase → use git town sync"
else
echo "❌ Git-town enforcement hook is NOT installed"
echo " Run: /git-town-workflow:hooks install"
fi
STATUS_HOOK_EOF
install - Install enforcement hooksuninstall - Remove enforcement hooksstatus - Show current hook status# Install hooks
/git-town-workflow:hooks install
# Check status
/git-town-workflow:hooks status
# Remove hooks
/git-town-workflow:hooks uninstall
| Issue | Cause | Solution |
|---|---|---|
| jq not found | jq not installed | brew install jq |
| Settings file not found | ~/.claude/ doesn't exist | Create with mkdir -p ~/.claude |
| Hook not blocking | Session not restarted | Restart Claude Code session |
| Invalid JSON error | Corrupted settings.json | Check JSON syntax or restore backup |
| Hook still active | Multiple hooks registered | Uninstall and reinstall to dedupe |
After this skill completes, reflect before closing the task:
Do NOT defer. The next invocation inherits whatever you leave behind.