99 lines
2.0 KiB
Bash
Executable File
99 lines
2.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Mirror SOURCE -> DEST while archiving files that would be deleted/overwritten.
|
|
# Archived files are moved under DEST/.archive/<timestamp>/ preserving hierarchy.
|
|
#
|
|
# Usage:
|
|
# bash scripts/utility/backup_mirror_with_archive.sh
|
|
# bash scripts/utility/backup_mirror_with_archive.sh --dry-run
|
|
# bash scripts/utility/backup_mirror_with_archive.sh --source /src --dest /dst
|
|
|
|
SOURCE="/home/rpotter/hypertower/"
|
|
DEST="/Muspelheim/PhD/00.3_hypertower/"
|
|
DRY_RUN=0
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--source)
|
|
SOURCE="$2"
|
|
shift 2
|
|
;;
|
|
--dest)
|
|
DEST="$2"
|
|
shift 2
|
|
;;
|
|
--dry-run)
|
|
DRY_RUN=1
|
|
shift
|
|
;;
|
|
*)
|
|
echo "Unknown argument: $1" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
ts="$(date +%Y%m%d_%H%M%S)"
|
|
archive_dir="${DEST%/}/.archive/${ts}"
|
|
|
|
mkdir -p "$archive_dir"
|
|
|
|
cmd=(
|
|
rsync -avh --progress
|
|
--delete
|
|
--backup
|
|
--backup-dir="$archive_dir"
|
|
# Directories with no backup value
|
|
--exclude=".git/"
|
|
--exclude=".claude/"
|
|
--exclude=".archive/"
|
|
# Large datasets stored elsewhere
|
|
--exclude="refuge/"
|
|
--exclude="Refuge/"
|
|
--exclude="REFUGE/"
|
|
--exclude="papila/"
|
|
--exclude="Papila/"
|
|
--exclude="PAPILA/"
|
|
# Python / general caches
|
|
--exclude="__pycache__/"
|
|
--exclude=".mypy_cache/"
|
|
--exclude=".ruff_cache/"
|
|
--exclude=".pytest_cache/"
|
|
--exclude=".cache/"
|
|
--exclude="*.pyc"
|
|
--exclude="*.pyo"
|
|
# Virtual environments
|
|
--exclude=".venv/"
|
|
--exclude="venv/"
|
|
--exclude="env/"
|
|
# Node
|
|
--exclude="node_modules/"
|
|
# Build / dist artifacts
|
|
--exclude="*.egg-info/"
|
|
--exclude="dist/"
|
|
--exclude="build/"
|
|
--exclude=".eggs/"
|
|
# IDE / editor metadata
|
|
--exclude=".idea/"
|
|
--exclude=".vscode/"
|
|
# OS metadata
|
|
--exclude=".DS_Store"
|
|
--exclude="Thumbs.db"
|
|
"${SOURCE%/}/"
|
|
"${DEST%/}/"
|
|
)
|
|
|
|
if [[ "$DRY_RUN" -eq 1 ]]; then
|
|
cmd+=(--dry-run)
|
|
fi
|
|
|
|
echo "Source: ${SOURCE%/}/"
|
|
echo "Dest: ${DEST%/}/"
|
|
echo "Archive: $archive_dir"
|
|
[[ "$DRY_RUN" -eq 1 ]] && echo "Mode: dry-run"
|
|
echo
|
|
|
|
"${cmd[@]}"
|
|
|