#!/usr/bin/env bash
# Install: ln -sf ../../scripts/git-hooks/pre-push .git/hooks/pre-push
#
# Mirror pushes to the tangled remote before allowing the origin push.
#
# Why: previously `origin` had two push URLs (github + tangled). Push fan-out
# was best-effort — if one side rejected, the other still succeeded and the
# rejected mirror silently drifted. This hook makes both sides atomic from the
# user's view: tangled push happens first, and if it fails the origin push
# aborts. No --no-verify on commits ever, so this is the trust boundary.
#
# Skipped when pushing to anything other than origin (so `git push tangled`
# directly does not recurse).

set -euo pipefail

remote_name="$1"

if [ "$remote_name" != "origin" ]; then
    exit 0
fi

# Read stdin (one line per ref being pushed) into refspec args. Skip deletions
# — let the user manage tangled deletions explicitly to avoid clobbering refs
# we forgot were only on the mirror.
ZERO=0000000000000000000000000000000000000000
refspecs=()
while read -r local_ref local_sha remote_ref remote_sha; do
    if [ "$local_sha" = "$ZERO" ]; then
        continue
    fi
    refspecs+=("${local_sha}:${remote_ref}")
done

if [ ${#refspecs[@]} -eq 0 ]; then
    exit 0
fi

echo "pre-push: mirroring ${#refspecs[@]} ref(s) to tangled before origin..."
if ! git push tangled "${refspecs[@]}"; then
    echo "pre-push: tangled rejected the push — aborting origin push to prevent drift." >&2
    echo "pre-push: reconcile tangled first (git fetch tangled; investigate), then retry." >&2
    exit 1
fi
echo "pre-push: tangled OK, proceeding with origin."
