77 lines
2.1 KiB
Bash
Executable File
77 lines
2.1 KiB
Bash
Executable File
#!/bin/bash
|
|
# Git audit: check ~/dev/ repos for unpushed changes
|
|
# Hourly: only fetch repos with local changes (dirty or ahead)
|
|
# --full: fetch all repos (daily at 6am)
|
|
# Reports anomalies only — silence = healthy
|
|
|
|
DEV_DIR="/home/johan/dev"
|
|
CLAWD_DIR="/home/johan/clawd"
|
|
STATE_FILE="/home/johan/clawd/memory/git-audit-lastfull.txt"
|
|
ANOMALIES=""
|
|
FULL=false
|
|
|
|
# Full sweep if --full flag or last full was >20h ago
|
|
if [ "${1:-}" = "--full" ]; then
|
|
FULL=true
|
|
elif [ -f "$STATE_FILE" ]; then
|
|
LAST=$(cat "$STATE_FILE")
|
|
NOW=$(date +%s)
|
|
AGE=$(( NOW - LAST ))
|
|
[ "$AGE" -gt 72000 ] && FULL=true
|
|
else
|
|
FULL=true
|
|
fi
|
|
|
|
audit_repo() {
|
|
local dir="$1"
|
|
local repo=$(basename "$dir")
|
|
|
|
# Check for remote
|
|
if ! git -C "$dir" remote get-url origin >/dev/null 2>&1; then
|
|
ANOMALIES+="❌ $repo: NO REMOTE\n"
|
|
return
|
|
fi
|
|
|
|
# Uncommitted changes
|
|
local DIRTY=$(git -C "$dir" status --porcelain 2>/dev/null)
|
|
local DIRTY_COUNT=0
|
|
if [ -n "$DIRTY" ]; then
|
|
DIRTY_COUNT=$(echo "$DIRTY" | wc -l)
|
|
fi
|
|
|
|
# Current branch
|
|
local BRANCH=$(git -C "$dir" rev-parse --abbrev-ref HEAD 2>/dev/null)
|
|
local AHEAD=0
|
|
if [ -n "$BRANCH" ] && git -C "$dir" rev-parse "origin/$BRANCH" >/dev/null 2>&1; then
|
|
AHEAD=$(git -C "$dir" rev-list --count "origin/$BRANCH..HEAD" 2>/dev/null || echo 0)
|
|
fi
|
|
|
|
# Only fetch if full mode OR repo has local changes
|
|
if $FULL || [ "$DIRTY_COUNT" -gt 0 ] || [ "$AHEAD" -gt 0 ]; then
|
|
timeout 5 git -C "$dir" fetch origin --quiet 2>/dev/null || true
|
|
# Recheck ahead after fetch
|
|
if [ -n "$BRANCH" ] && git -C "$dir" rev-parse "origin/$BRANCH" >/dev/null 2>&1; then
|
|
AHEAD=$(git -C "$dir" rev-list --count "origin/$BRANCH..HEAD" 2>/dev/null || echo 0)
|
|
fi
|
|
fi
|
|
|
|
[ "$DIRTY_COUNT" -gt 0 ] && ANOMALIES+="⚠️ $repo: $DIRTY_COUNT uncommitted file(s)\n"
|
|
[ "$AHEAD" -gt 0 ] && ANOMALIES+="🔺 $repo: $AHEAD unpushed commit(s) on $BRANCH\n"
|
|
}
|
|
|
|
for dir in "$DEV_DIR"/*/; do
|
|
[ -d "$dir/.git" ] || continue
|
|
audit_repo "$dir"
|
|
done
|
|
|
|
[ -d "$CLAWD_DIR/.git" ] && audit_repo "$CLAWD_DIR"
|
|
|
|
$FULL && date +%s > "$STATE_FILE"
|
|
|
|
if [ -n "$ANOMALIES" ]; then
|
|
echo -e "Git audit found issues:\n$ANOMALIES"
|
|
exit 1
|
|
else
|
|
exit 0
|
|
fi
|