#!/usr/bin/env bash set -euo pipefail if [[ $# -gt 1 ]]; then echo "Usage: $0 [path/to/env-file]" >&2 exit 2 fi SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" if [[ $# -eq 1 ]]; then ENV_FILE="$1" elif [[ -f "$SCRIPT_DIR/backup_rsync_git.env" ]]; then ENV_FILE="$SCRIPT_DIR/backup_rsync_git.env" else ENV_FILE="$SCRIPT_DIR/.env" fi if [[ ! -f "$ENV_FILE" ]]; then echo "Env file not found: $ENV_FILE" >&2 exit 1 fi # shellcheck disable=SC1090 source "$ENV_FILE" required_vars=( RSYNC_SOURCE RSYNC_TARGET_DIR COMMIT_MESSAGE_PREFIX ) for var in "${required_vars[@]}"; do if [[ -z "${!var:-}" ]]; then echo "Missing required env var: $var" >&2 exit 1 fi done if [[ -z "${RSYNC_RSH:-}" && -z "${SSH_KEY_FILE:-}" ]]; then echo "Missing SSH config: set SSH_KEY_FILE or RSYNC_RSH" >&2 exit 1 fi if [[ -n "${SSH_KEY_FILE:-}" && ! -r "$SSH_KEY_FILE" ]]; then echo "SSH key file not readable: $SSH_KEY_FILE" >&2 exit 1 fi mkdir -p "$RSYNC_TARGET_DIR" repo_abs="$(cd "$RSYNC_TARGET_DIR" && pwd)" rel_target="." if [[ ! -d "$repo_abs/.git" ]]; then git -C "$repo_abs" init -b main >/dev/null fi git_target() { git --git-dir="$repo_abs/.git" --work-tree="$repo_abs" "$@" } if [[ -n "${RSYNC_RSH:-}" ]]; then rsync_rsh="$RSYNC_RSH" else ssh_options="${SSH_OPTIONS:--o IdentitiesOnly=yes -o StrictHostKeyChecking=yes}" rsync_rsh="ssh -i $SSH_KEY_FILE $ssh_options" fi if [[ -n "${rsync_rsh:-}" ]]; then rsync -az --delete -e "$rsync_rsh" "$RSYNC_SOURCE" "$repo_abs/" else rsync -az --delete "$RSYNC_SOURCE" "$repo_abs/" fi git_target add -A -- "$rel_target" if git_target diff --cached --quiet -- "$rel_target"; then exit 0 fi timestamp="$(date '+%Y-%m-%d %H:%M:%S')" git_target commit -m "$COMMIT_MESSAGE_PREFIX $timestamp" -- "$rel_target"