#!/usr/bin/env bash # worktree-audit.sh — Quick diagnostic: list all worktrees on the system # Use this to understand the scope before running the cleanup script. # # Output: CSV to stdout, summary to stderr set -euo pipefail echo "=== Worktree Audit — $(date '+%Y-%m-%d %H:%M:%S') ===" >&2 # Find repos REPOS=$(find "$HOME" -maxdepth 5 -name ".git" -type d \ -not -path "*/node_modules/*" \ -not -path "*/.cache/*" \ -not -path "*/vendor/*" \ 2>/dev/null || true) echo "repo_path,worktree_path,branch,locked,head_commit,hours_since_mod" TOTAL=0 while IFS= read -r gitdir; do repo="${gitdir%/.git}" cd "$repo" || continue wt_list=$(git worktree list --porcelain 2>/dev/null) || continue [[ -z "$wt_list" ]] && continue current_path="" current_locked="no" current_head="" while IFS= read -r line; do if [[ "$line" =~ ^worktree\ (.+)$ ]]; then current_path="${BASH_REMATCH[1]}" current_locked="no" current_head="" elif [[ "$line" == "locked" ]]; then current_locked="yes" elif [[ "$line" =~ ^HEAD\ (.+)$ ]]; then current_head="${BASH_REMATCH[1]}" elif [[ -z "$line" ]] && [[ -n "$current_path" ]]; then hours="N/A" if [[ -d "$current_path" ]]; then last_mod=$(find "$current_path" -type f -not -path '*/.git/*' -printf '%T@\n' 2>/dev/null | sort -rn | head -1) if [[ -n "$last_mod" ]]; then now=$(date +%s) hours=$(( (now - ${last_mod%.*}) / 3600 )) fi fi echo "$repo,$current_path,$current_head,$current_locked,,$hours" TOTAL=$((TOTAL + 1)) current_path="" current_locked="no" current_head="" fi done <<< "$wt_list" # Last entry if [[ -n "$current_path" ]]; then hours="N/A" if [[ -d "$current_path" ]]; then last_mod=$(find "$current_path" -type f -not -path '*/.git/*' -printf '%T@\n' 2>/dev/null | sort -rn | head -1) if [[ -n "$last_mod" ]]; then now=$(date +%s) hours=$(( (now - ${last_mod%.*}) / 3600 )) fi fi echo "$repo,$current_path,$current_head,$current_locked,,$hours" TOTAL=$((TOTAL + 1)) fi done <<< "$REPOS" echo "" >&2 echo "Total worktrees: $TOTAL" >&2 echo "Target: <20" >&2 echo "" >&2 echo "To clean up: ./worktree-cleanup.sh --dry-run" >&2