#!/bin/sh
# gitgud-prereceive — invoked by pre-receive in each bare repo.
#
# Reads `<old> <new> <ref>` lines from stdin and POSTs them to the
# Phoenix node for branch-protection evaluation. If Phoenix says DENY,
# we print the reason on stderr (visible to the pushing client) and
# exit non-zero so git aborts the push.
#
# **Fail-closed**: if the protection backend is unreachable (curl
# missing, Phoenix down, DNS broken, etc.), the push is REJECTED.
# Better to refuse than to silently bypass branch protection. Operator
# can override by setting `GITGUD_PREHOOK_FAIL_OPEN=1` if they
# explicitly want fail-open behavior (e.g. during an emergency
# unblock).
set -eu
GITGUD_PREHOOK_URL="${GITGUD_PREHOOK_URL:-http://127.0.0.1:4000/_hooks/pre-receive}"
REPO_PATH="${GIT_DIR:-$(pwd)}"
REPO_PATH="$(cd "$REPO_PATH" && pwd)"
STDIN_PAYLOAD="$(cat)"
if ! command -v curl >/dev/null 2>&1; then
echo "gitgud: curl not installed; cannot reach protection backend" >&2
if [ "${GITGUD_PREHOOK_FAIL_OPEN:-}" = "1" ]; then
echo "gitgud: GITGUD_PREHOOK_FAIL_OPEN=1 — allowing push anyway" >&2
exit 0
fi
exit 1
fi
RESP=$(curl -sf -X POST \
-H "content-type: text/plain" \
-H "x-repo-path: ${REPO_PATH}" \
--data-binary "${STDIN_PAYLOAD}" \
"${GITGUD_PREHOOK_URL}" 2>/dev/null) || {
echo "gitgud: protection backend unreachable at ${GITGUD_PREHOOK_URL}" >&2
if [ "${GITGUD_PREHOOK_FAIL_OPEN:-}" = "1" ]; then
echo "gitgud: GITGUD_PREHOOK_FAIL_OPEN=1 — allowing push anyway" >&2
exit 0
fi
echo "gitgud: refusing push (branch protection cannot be evaluated)" >&2
exit 1
}
STATUS=$(printf '%s' "$RESP" | head -n1 | awk '{print $1}')
REASON=$(printf '%s' "$RESP" | tail -n +2)
if [ "$STATUS" = "OK" ]; then
exit 0
fi
echo "gitgud: push denied" >&2
printf '%s\n' "$REASON" >&2
exit 1
1.8 KiB · text
5af55d9