Protect main: git hooks + Claude Code deny rules #3

Merged
christian merged 4 commits from chore/deny-push-main into main 2026-10-21 00:58:31 +02:00
2 changed files with 19 additions and 2 deletions
Showing only changes of commit 480ed6a8b2 - Show all commits

No files matched your search

+4 -1
View File
@@ -5,10 +5,13 @@
# (and so their hooks) run outside the sandbox. Re-run after changing anything in .githooks/.
set -e
cd "$(dirname "$0")/.."
if ! hooks=$(git rev-parse --git-path hooks 2>/dev/null); then
# Use the repo's own hooks directory, not `git rev-parse --git-path hooks`: that follows a
# (possibly global) core.hooksPath and would install these hooks for every repo.
if ! common=$(git rev-parse --git-common-dir 2>/dev/null); then
echo "install-hooks: not a git checkout; skipping." >&2
exit 0
fi
hooks="$common/hooks"
mkdir -p "$hooks"
for hook in .githooks/*; do
cp "$hook" "$hooks/"
+15 -1
View File
@@ -1,7 +1,7 @@
import { test, after } from "node:test";
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { mkdtempSync, rmSync, cpSync, statSync } from "node:fs";
import { mkdtempSync, rmSync, cpSync, statSync, writeFileSync, existsSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
@@ -74,6 +74,20 @@ test("install-hooks copies every hook into .git/hooks as an executable", () => {
}
});
test("install-hooks ignores a global core.hooksPath", () => {
const repo = repoOn("fix/x");
const elsewhere = mkdtempSync(join(tmpdir(), "todo-hooks-"));
dirs.push(elsewhere);
const globalConfig = join(elsewhere, "gitconfig");
writeFileSync(globalConfig, `[core]\n\thooksPath = ${elsewhere}\n`);
cpSync(join(ROOT, "scripts"), join(repo, "scripts"), { recursive: true });
cpSync(HOOKS, join(repo, ".githooks"), { recursive: true });
const res = run("sh", [join(repo, "scripts", "install-hooks.sh")], { env: { ...env, GIT_CONFIG_GLOBAL: globalConfig } });
assert.equal(res.status, 0, res.stderr);
assert.ok(existsSync(join(repo, ".git", "hooks", "pre-push")));
assert.equal(existsSync(join(elsewhere, "pre-push")), false);
});
test("install-hooks skips cleanly outside a git checkout", () => {
const dir = mkdtempSync(join(tmpdir(), "todo-hooks-"));
dirs.push(dir);