mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-09 12:17:13 +00:00
A merge commit bypassed every signature check: test-signed only inspects HEAD and the pre-commit hook does not run for merge commits. Add scripts/git/assert_merge_signed.sh, which fails when any commit the merge brings in (HEAD..MERGE_HEAD) reports %G? status N, wire it up as make test-merge-signed, and register it as a pre-merge-commit hook so pre-commit install now also installs that hook type. Fast-forward merges create no commit and skip the hook (use --no-ff to gate them); conflicted merges fall back to the regular pre-commit and pre-push gates. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
24 lines
876 B
Bash
Executable File
24 lines
876 B
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Pre-merge-commit gate: every commit the merge brings in (HEAD..MERGE_HEAD)
|
|
# must carry a signature. `git log %G?` yields N for unsigned; any other
|
|
# status counts as signed, matching the test-signed HEAD gate.
|
|
|
|
git_dir="$(git rev-parse --git-dir)"
|
|
if [ ! -f "${git_dir}/MERGE_HEAD" ]; then
|
|
echo "❌ No merge in progress (MERGE_HEAD missing); this gate runs during git merge." >&2
|
|
exit 1
|
|
fi
|
|
|
|
unsigned="$(git log --pretty='%H %G? %s' HEAD..MERGE_HEAD | awk '$2 == "N"')"
|
|
if [ -n "${unsigned}" ]; then
|
|
echo "❌ Unsigned commit(s) coming in from the merged branch:" >&2
|
|
printf '%s\n' "${unsigned}" >&2
|
|
echo "Sign them (git rebase --exec 'git commit --amend --no-edit -S' or git-sign-push) and retry the merge." >&2
|
|
exit 1
|
|
fi
|
|
|
|
count="$(git rev-list --count HEAD..MERGE_HEAD)"
|
|
echo "✅ All ${count} incoming commit(s) are signed."
|