#!/bin/sh # # update-bare-repo.sh set -eu set -o pipefail TMP_BEFORE=$(mktemp) || exit 1 TMP_AFTER=$(mktemp) || { rm -f "$TMP_BEFORE"; exit 1; } TMP_CHANGES=$(mktemp) || { rm -f "$TMP_BEFORE" "$TMP_AFTER"; exit 1; } REPO=$2 cd "$1" cleanup() { rm -f "$TMP_BEFORE" "$TMP_AFTER" "$TMP_CHANGES" } trap cleanup EXIT INT TERM # Save refs before update git for-each-ref --format='%(refname) %(objectname)' "refs/heads/" >"$TMP_BEFORE" 2>/dev/null # Update if ! git fetch --all --prune --tags --verbose ; then echo "git remote update failed" >&2 exit 3 fi git for-each-ref --format='%(refname:short)' refs/heads | while read br; do if git show-ref --verify --quiet refs/remotes/origin/"$br"; then target_sha=$(git rev-parse "origin/$br") curr_sha=$(git rev-parse refs/heads/"$br") if [ "$target_sha" != "$curr_sha" ]; then echo "Updating $br -> origin/$br ($(git rev-parse --short "origin/$br"))" git update-ref refs/heads/"$br" "$target_sha" || { echo "Failed to update $br"; exit 1; } else echo "Up-to-date: $br" fi else echo "No origin/$br, skipping" fi done # Save refs after update git for-each-ref --format='%(refname) %(objectname)' "refs/heads/" >"$TMP_AFTER" 2>/dev/null # Produce changed refs: oldsha newsha refname # If a ref did not exist before, oldsha = 000...0 awk 'NR==FNR{m[$1]=$2;next} { old=m[$1]; if(old=="") old="0000000000000000000000000000000000000000"; if(old!=$2) print old, $2, $1 }' "$TMP_BEFORE" "$TMP_AFTER" >"$TMP_CHANGES" # If no changes, exit if [ ! -s "$TMP_CHANGES" ]; then echo "No remote changes detected for ${REPO}." exit 0 fi # Call the real post-receive hook with stdin lines # emulate server hook environment GIT_DIR=$(git rev-parse --git-dir 2>/dev/null) || { echo "Not a git repository." >&2; exit 4; } # Export GIT_DIR for the hook export GIT_DIR export GITEA_PUSHER_ID=1 export GITEA_REPO_NAME=${REPO} export GITEA_REPO_USER_NAME=FreeBSD export SSH_ORIGINAL_COMMAND=gitea-internal forgejo hook post-receive < "${TMP_CHANGES}" # Exit with hook status exit $?