#!/usr/bin/env bash set -euo pipefail # Default-Basisverzeichnis BASE_DIR="$HOME/git-projekte" SHOW_ALL=false SHORT_MODE=false # --- Farben ------------------------------------------------------------ if [ -t 1 ]; then C_RED=$'\033[31m' C_GREEN=$'\033[32m' C_YELLOW=$'\033[33m' C_CYAN=$'\033[36m' C_BOLD=$'\033[1m' C_RESET=$'\033[0m' else C_RED=""; C_GREEN=""; C_YELLOW=""; C_CYAN=""; C_BOLD=""; C_RESET="" fi # --- Argumente parsen -------------------------------------------------- while [[ $# -gt 0 ]]; do case "$1" in -a|--all) SHOW_ALL=true shift ;; -s|--short) SHORT_MODE=true shift ;; -p|--path) BASE_DIR="$2" shift 2 ;; -h|--help) cat <&2 exit 2 ;; esac done # --- Checks ------------------------------------------------------------ if [ ! -d "$BASE_DIR" ]; then echo "Verzeichnis $BASE_DIR existiert nicht – nichts zu prüfen." exit 0 fi echo "Suche Git-Repositories unter: $BASE_DIR" echo find_git_dirs() { find "$BASE_DIR" -type d -name ".git" -print 2>/dev/null } # --- .git-Verzeichnisse einsammeln & sortieren ------------------------ gitdirs=() while IFS= read -r gitdir; do gitdirs+=( "$gitdir" ) done < <(find_git_dirs) if [ ${#gitdirs[@]} -eq 0 ]; then echo "Keine Git-Repositories gefunden." exit 0 fi IFS=$'\n' sorted_gitdirs=( $(printf '%s\n' "${gitdirs[@]}" | sort) ) unset IFS # --- Auswertung -------------------------------------------------------- total=0 dirty=0 clean=0 for gitdir in "${sorted_gitdirs[@]}"; do repo_dir="${gitdir%/.git}" ((total++)) cd "$repo_dir" || continue # Lokale, nicht committete Änderungen? status_output="$(git status --porcelain 2>/dev/null || echo "")" has_local_changes=false if [[ -n "$status_output" ]]; then has_local_changes=true fi # Commits vor/nach Upstream? ahead=0 behind=0 if upstream_info=$(git rev-list --left-right --count "@{u}...HEAD" 2>/dev/null); then read -r behind ahead <<<"$upstream_info" fi is_dirty=false $has_local_changes && is_dirty=true ((ahead > 0)) && is_dirty=true ((behind > 0)) && is_dirty=true if $is_dirty; then ((dirty++)) else ((clean++)) $SHOW_ALL || continue fi # Zusammenfassungstext bauen summary="" $has_local_changes && summary+="lokale Änderungen; " ((ahead > 0)) && summary+="$ahead nicht gepushte Commits; " ((behind > 0)) && summary+="$behind nicht gepullte Commits; " summary="${summary%; }" [ -z "$summary" ] && summary="clean" if $SHORT_MODE; then # eine Zeile pro Repo if $is_dirty; then printf "%sDIRTY%s %s - %s\n" "$C_RED" "$C_RESET" "$repo_dir" "$summary" else printf "%sCLEAN%s %s - %s\n" "$C_GREEN" "$C_RESET" "$repo_dir" "$summary" fi else # detailliertere Ausgabe if $is_dirty; then printf "%s▸ %s%s\n" "$C_RED" "$repo_dir" "$C_RESET" else printf "%s▸ %s%s\n" "$C_GREEN" "$repo_dir" "$C_RESET" fi printf " %s%s%s\n\n" "$C_CYAN" "$summary" "$C_RESET" fi done # --- Zusammenfassung --------------------------------------------------- echo "${C_BOLD}Gesamt:${C_RESET} $total Repositories" echo "${C_GREEN}Clean:${C_RESET} $clean" echo "${C_RED}Dirty:${C_RESET} $dirty" echo if ((dirty == 0)); then echo "Alle gefundenen Git-Repositories in $BASE_DIR sind sauber. ✅" exit 0 else echo "$dirty Repository(s) mit offenen Änderungen. ⚠️" exit 1 fi