|
#!/usr/bin/env bash |
|
|
|
# Standalone Git Repository Report Script |
|
|
|
# Configuration (can be modified here directly) |
|
DEFAULT_GIT_CLONE_PATH="$HOME/repositories" # Default path to search for git repos |
|
|
|
# --- Helper Functions (Standalone implementations) --- |
|
|
|
# For standalone, let's use simple echo with prefixes instead of log_warning/log_info |
|
log_warning() { |
|
echo "[WARNING] $@" |
|
} |
|
|
|
log_info() { |
|
echo "[INFO] $@" |
|
} |
|
|
|
|
|
# --- Script Functions (Modified for standalone) --- |
|
|
|
fn_git_report__look_for_git_repo_recursively() { |
|
# inspired by https://stackoverflow.com/a/23344072 |
|
local folder |
|
local git_repositories |
|
folder="$1" |
|
|
|
# Find command that handle spaces in paths |
|
git_repositories=$(find "$folder" -type d \( -exec test -e {}/.ignore \; -prune \) -o \( -exec test -d {}/.git \; -prune -print0 \) | tr '\0' '\n') |
|
|
|
# Filter out empty lines from find output (if any) |
|
git_repositories=$(echo "$git_repositories" | grep -v '^$') |
|
|
|
echo "$git_repositories" |
|
} |
|
|
|
fn_git_report__process_repo() { |
|
local repo_path |
|
local status |
|
repo_path="$1" |
|
|
|
if ! cd "$repo_path"; then |
|
log_warning "Could not change directory to: $repo_path. Skipping." |
|
return 1 # Indicate failure to cd, but continue script |
|
fi |
|
|
|
status="$(git status -s)" |
|
|
|
if [ -n "$status" ]; then |
|
log_warning "Git repo with pending changes: $repo_path" |
|
echo "" |
|
echo " Path: $repo_path" |
|
remote_url=$(git remote get-url origin 2>/dev/null) # Capture remote URL or handle error if no remote |
|
if [ -n "$remote_url" ]; then |
|
echo " Remote: $remote_url" |
|
else |
|
echo " Remote: No remote configured (origin)" |
|
fi |
|
branch_name=$(git branch --show-current 2>/dev/null) # Capture branch name or handle error if detached HEAD |
|
if [ -n "$branch_name" ]; then |
|
echo " Branch: $branch_name" |
|
else |
|
echo " Branch: Detached HEAD" |
|
fi |
|
while IFS= read -r line; do |
|
printf " %s\n" "$line" |
|
done <<<"$status" |
|
echo "" |
|
else |
|
log_info "Git repo clean: $repo_path" |
|
fi |
|
return 0 # Indicate successful processing of repo |
|
} |
|
|
|
fn_git_report() { |
|
|
|
local git_default_clone_path |
|
git_default_clone_path="${DEFAULT_GIT_CLONE_PATH}" # Use the configured default |
|
|
|
if [ ! -d "$git_default_clone_path" ]; then |
|
log_warning "Default git clone path '$git_default_clone_path' does not exist or is not a directory." |
|
return 1 # Indicate failure, path is invalid |
|
fi |
|
|
|
|
|
local repos_found |
|
repos_found=0 |
|
local repos_with_pending_changes=0 |
|
|
|
while IFS= read -r repo; do |
|
repos_found=$((repos_found + 1)) |
|
if fn_git_report__process_repo "$repo"; then |
|
: # Processed successfully, no need to increment pending changes count here as it's already logged in process_repo |
|
: # if process_repo returns 0, it's considered processed. if it returned 1, it failed to cd and was skipped. |
|
status_check=$(git status -s 2>/dev/null) # Re-check status within process_repo context, capture status again |
|
if [ -n "$status_check" ]; then |
|
repos_with_pending_changes=$((repos_with_pending_changes + 1)) |
|
fi |
|
|
|
else |
|
log_warning "Failed to process repo at '$repo'. Skipping." |
|
fi |
|
done <<<"$(fn_git_report__look_for_git_repo_recursively "$git_default_clone_path")" |
|
|
|
echo "" |
|
echo "--- Summary ---" |
|
echo "Total git repositories scanned: $repos_found" |
|
echo "Repositories with pending changes: $repos_with_pending_changes" |
|
|
|
if [ "$repos_with_pending_changes" -gt 0 ]; then |
|
return 1 # Indicate that there were repos with pending changes (non-zero exit code) |
|
else |
|
return 0 # Indicate success, no repos with pending changes (zero exit code) |
|
fi |
|
|
|
} |
|
|
|
|
|
# --- Main execution --- |
|
fn_git_report |