#!/usr/bin/env bash set -Eeuo pipefail SRC_ROOT="/works/git/" DEST_USER="cvtt" DEST_HOST="hs01.cvtt.vpn" DEST_BASE="/backup/git/snapshots" TODAY="$(date +%F)" DEST_TODAY="${DEST_BASE}/${TODAY}" SSH_OPTS="ssh -o BatchMode=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" COMMON= COMMON+="-avHAX" COMMON+=" --numeric-ids" COMMON+=" --delete" COMMON+=" --partial" COMMON+=" --delay-updates" COMMON+=" --no-inc-recursive" COMMON+=" --mkpath" COMMON+=" -e '${SSH_OPTS}'" COMMON+=" --exclude '**/*.lock'" COMMON+=" --exclude '**/hooks/*.sample'" # Two-phase to avoid refs racing PHASE1= PHASE1+="${COMMON}" PHASE1+=" --exclude '**/refs/**'" PHASE1+=" --exclude '**/packed-refs'" PHASE1+=" --exclude '**/HEAD'" PHASE2= PHASE2+="${COMMON}" PHASE2+=" --include '**/refs/**'" PHASE2+=" --include '**/packed-refs'" PHASE2+=" --include '**/HEAD'" PHASE2+=" --include '*/'" PHASE2+=" --exclude '*'" TARGET="${DEST_USER}@${DEST_HOST}:${DEST_TODAY%/}/" echo "== Phase 1 ==" Cmd="rsync ${PHASE1} ${SRC_ROOT} ${TARGET}" echo ${Cmd} && eval ${Cmd} echo "== Phase 2 ==" Cmd="rsync ${PHASE2} ${SRC_ROOT} ${TARGET}" echo ${Cmd} && eval ${Cmd} echo "== Consistency re-check ==" echo ${Cmd} && eval ${Cmd} echo "Snapshot completed: $DEST_TODAY"