#!/bin/bash # Auto-save any repos with uncommitted changes to Gitea # Runs daily via cron — stdout is delivered to Telegram # Add new repos in the REPOS array below. # For root-owned dirs, add ":sudo" as the third colon-delimited field. set -euo pipefail DATE=$(date '+%Y-%m-%d') LOGFILE="$HOME/.hermes/logs/git-autosave.log" mkdir -p "$HOME/.hermes/logs" # Format: path:branch:prefix # prefix: 'sudo' for root-owned dirs, empty for normal REPOS=( "/path/to/project-1:main" "/path/to/project-2:main" "/etc/nginx:main:sudo" ) SAVED=() CLEAN=() ERRORS=() for entry in "${REPOS[@]}"; do IFS=':' read -r DIR BRANCH PREFIX <<< "$entry" NAME=$(basename "$DIR") GIT="${PREFIX:+sudo }git" if [ ! -d "$DIR/.git" ]; then echo "[$DATE] SKIP $DIR — no .git" >> "$LOGFILE" continue fi cd "$DIR" if [ -z "$($GIT status --porcelain 2>/dev/null)" ]; then echo "[$DATE] CLEAN $NAME" >> "$LOGFILE" CLEAN+=("$NAME") continue fi $GIT pull --rebase origin "$BRANCH" 2>/dev/null || true $GIT add -A if $GIT commit -m "auto-save $DATE"; then if $GIT push origin "$BRANCH" 2>/dev/null; then echo "[$DATE] SAVED $NAME" >> "$LOGFILE" SAVED+=("$NAME") else echo "[$DATE] PUSH FAILED $NAME" >> "$LOGFILE" ERRORS+=("$NAME (push failed)") fi else echo "[$DATE] COMMIT FAILED $NAME" >> "$LOGFILE" ERRORS+=("$NAME (commit failed)") fi done MSG="" if [ ${#SAVED[@]} -gt 0 ]; then MSG="${MSG}✓ Saved: ${SAVED[*]}\n" fi if [ ${#CLEAN[@]} -gt 0 ]; then MSG="${MSG}— Clean: ${CLEAN[*]}\n" fi if [ ${#ERRORS[@]} -gt 0 ]; then MSG="${MSG}✗ Errors: ${ERRORS[*]}\n" fi if [ -n "$MSG" ]; then echo -e "Gitea auto-save $DATE\n${MSG}" fi