From 8be6130725e9caa3413ff1fd0200079864e37267 Mon Sep 17 00:00:00 2001 From: "Joseph T. French" Date: Tue, 14 Jul 2026 00:35:33 -0500 Subject: [PATCH 1/2] chore(githooks): guard pushes to protected branches Add a pre-push hook that rejects direct pushes whose destination ref is main, master, or release/*, so those land only through pull requests. Feature branches pass through. Picked up via the existing core.hooksPath=.githooks wiring. Also move git push from deny to allow in the Claude Code settings, with the hook as the branch-level guard. --- .claude/settings.json | 2 +- .githooks/pre-push | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100755 .githooks/pre-push diff --git a/.claude/settings.json b/.claude/settings.json index b06b7c5..b113566 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -11,6 +11,7 @@ "Bash(git branch -r:*)", "Bash(git branch -v:*)", "Bash(git fetch:*)", + "Bash(git push:*)", "Bash(ls:*)", "Bash(tree:*)", "Bash(wc:*)", @@ -50,7 +51,6 @@ "mcp__ide__getDiagnostics" ], "deny": [ - "Bash(git push:*)", "Bash(git reset:*)", "Bash(git clean:*)", "Bash(git branch -D:*)", diff --git a/.githooks/pre-push b/.githooks/pre-push new file mode 100755 index 0000000..47dfb8b --- /dev/null +++ b/.githooks/pre-push @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# +# Block direct pushes to protected branches (main / master / release/*). +# Feature branches pass through untouched. Git feeds each ref being pushed on +# stdin as " ", so this checks +# the resolved destination and catches bare `git push` as well as explicit ones. +# GitHub branch protection is the server-side backstop; this is the local guard. +set -euo pipefail + +protected='^refs/heads/(main|master|release/.*)$' + +while read -r _local_ref _local_sha remote_ref _remote_sha; do + if [[ "$remote_ref" =~ $protected ]]; then + echo "pre-push: direct pushes to '${remote_ref#refs/heads/}' are blocked - open a PR instead." >&2 + exit 1 + fi +done + +exit 0 From 975100c08948318d3f12ded1fec66c4ccc403b10 Mon Sep 17 00:00:00 2001 From: "Joseph T. French" Date: Tue, 14 Jul 2026 01:06:56 -0500 Subject: [PATCH 2/2] chore(githooks): install hooks via justfile venv recipe --- justfile | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/justfile b/justfile index d7fc96c..86a8489 100644 --- a/justfile +++ b/justfile @@ -5,10 +5,15 @@ default: # Create virtual environment and install dependencies venv: pip install uv - uv venv - source .venv/bin/activate + uv venv + source .venv/bin/activate + @just install-hooks @just install +# Install git hooks (points core.hooksPath at .githooks; idempotent, safe to re-run) +install-hooks: + git config core.hooksPath .githooks + # Install dependencies install: uv pip install -e ".[dev]"