diff --git a/code/backup_rsync_git.env.example b/code/backup_rsync_git.env.example index 2b4428c..96e8330 100644 --- a/code/backup_rsync_git.env.example +++ b/code/backup_rsync_git.env.example @@ -1,11 +1,9 @@ # Remote rsync source. Example: backup@example.com:/srv/data/project/ RSYNC_SOURCE="user@example.com:/path/to/source/" -# Local sync destination (must be a directory inside GIT_REPO_DIR) -RSYNC_TARGET_DIR="/path/to/monorepo/backups/source" - -# Local monorepo path -GIT_REPO_DIR="/path/to/monorepo" +# Local target directory for rsync; this directory is also used as git repository +# Must be outside the main project repository +RSYNC_TARGET_DIR="/path/to/backup-repo" # Prefix for commit message (timestamp is appended automatically) COMMIT_MESSAGE_PREFIX="backup: rsync sync" diff --git a/code/backup_rsync_git.sh b/code/backup_rsync_git.sh index 2e5b659..76e7cfc 100755 --- a/code/backup_rsync_git.sh +++ b/code/backup_rsync_git.sh @@ -2,11 +2,20 @@ set -euo pipefail if [[ $# -gt 1 ]]; then - echo "Usage: $0 [path/to/.env]" >&2 + echo "Usage: $0 [path/to/env-file]" >&2 exit 2 fi -ENV_FILE="${1:-$(dirname "$0")/.env}" +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 @@ -18,7 +27,6 @@ source "$ENV_FILE" required_vars=( RSYNC_SOURCE RSYNC_TARGET_DIR - GIT_REPO_DIR COMMIT_MESSAGE_PREFIX ) @@ -31,30 +39,29 @@ done mkdir -p "$RSYNC_TARGET_DIR" -repo_abs="$(cd "$GIT_REPO_DIR" && pwd)" -target_abs="$(cd "$RSYNC_TARGET_DIR" && pwd)" +repo_abs="$(cd "$RSYNC_TARGET_DIR" && pwd)" -case "$target_abs" in - "$repo_abs"/*) ;; - *) - echo "RSYNC_TARGET_DIR must be inside GIT_REPO_DIR" >&2 - exit 1 - ;; -esac +rel_target="." -rel_target="${target_abs#"$repo_abs"/}" - -if [[ -n "${RSYNC_RSH:-}" ]]; then - rsync -az --delete -e "$RSYNC_RSH" "$RSYNC_SOURCE" "$RSYNC_TARGET_DIR/" -else - rsync -az --delete "$RSYNC_SOURCE" "$RSYNC_TARGET_DIR/" +if [[ ! -d "$repo_abs/.git" ]]; then + git -C "$repo_abs" init >/dev/null fi -git -C "$GIT_REPO_DIR" add -A -- "$rel_target" +git_target() { + git --git-dir="$repo_abs/.git" --work-tree="$repo_abs" "$@" +} -if git -C "$GIT_REPO_DIR" diff --cached --quiet -- "$rel_target"; then +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 -C "$GIT_REPO_DIR" commit -m "$COMMIT_MESSAGE_PREFIX $timestamp" -- "$rel_target" +git_target commit -m "$COMMIT_MESSAGE_PREFIX $timestamp" -- "$rel_target"