From 6567fd50d887857cd3afb2843fa66b092b81bd9a Mon Sep 17 00:00:00 2001 From: Cryptoval Trading Technologies Date: Sun, 14 Sep 2025 01:10:24 +0000 Subject: [PATCH] initial backup-git.sh --- backup/backup-git.sh | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100755 backup/backup-git.sh diff --git a/backup/backup-git.sh b/backup/backup-git.sh new file mode 100755 index 0000000..da6529a --- /dev/null +++ b/backup/backup-git.sh @@ -0,0 +1,53 @@ +#!/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" +