Skip to content

Instantly share code, notes, and snippets.

@sethladd
Last active May 21, 2025 16:08
Show Gist options
  • Save sethladd/65717aefc6bd4cc683e5b715dfc35139 to your computer and use it in GitHub Desktop.
Save sethladd/65717aefc6bd4cc683e5b715dfc35139 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Default start and end dates
DEFAULT_START_DATE="2025-01-01"
DEFAULT_END_DATE="2025-05-21"
# Initialize variables with default values
START_DATE="$DEFAULT_START_DATE"
END_DATE="$DEFAULT_END_DATE"
DISPLAY_EMAILS=false
# Parse command-line arguments
while [[ "$#" -gt 0 ]]; do
case "$1" in
--display-emails)
DISPLAY_EMAILS=true
;;
--start-date)
if [[ -n "$2" ]]; then
START_DATE="$2"
shift # Consume the argument value
else
echo "Error: --start-date requires a date value (YYYY-MM-DD)."
exit 1
fi
;;
--end-date)
if [[ -n "$2" ]]; then
END_DATE="$2"
shift # Consume the argument value
else
echo "Error: --end-date requires a date value (YYYY-MM-DD)."
exit 1
fi
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 [--display-emails] [--start-date YYYY-MM-DD] [--end-date YYYY-MM-DD]"
exit 1
;;
esac
shift # Consume the argument name
done
# Create a temporary file to store all collected author emails
TEMP_EMAIL_FILE=$(mktemp)
echo "Searching for Git repositories in subdirectories and collecting unique contributors..."
echo "Date range: $START_DATE to $END_DATE"
echo "--------------------------------------------------"
# Get the current working directory to return to later
CURRENT_DIR=$(pwd)
# Loop through each immediate subdirectory
# -maxdepth 1 ensures we only look at direct children, not nested sub-repos.
# -type d filters for directories only.
for dir in */; do
# Remove the trailing slash from the directory name for cleaner output
dir_name="${dir%/}"
# Change into the subdirectory, suppressing output
pushd "$dir_name" > /dev/null 2>&1
# Check if the current subdirectory is a Git repository
if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
echo "Processing repository: $dir_name"
# Get author emails from commits within the specified date range
# and append them to the temporary file.
git log --since="$START_DATE" --until="$END_DATE" --format='%aE' >> "$TEMP_EMAIL_FILE"
else
echo "Skipping '$dir_name': Not a Git repository."
fi
# Return to the original directory, suppressing output
popd > /dev/null 2>&1
done
echo "--------------------------------------------------"
echo "Aggregation complete. Calculating unique contributors..."
# Count the total number of unique contributors from the collected emails
# sort -u sorts the emails and removes duplicates.
# wc -l counts the number of lines (which are now unique emails).
TOTAL_UNIQUE_CONTRIBUTORS=$(cat "$TEMP_EMAIL_FILE" | sort -u | wc -l)
echo "--------------------------------------------------"
echo "Total number of unique contributors across all scanned repositories: $TOTAL_UNIQUE_CONTRIBUTORS"
echo "--------------------------------------------------"
# Conditionally display the list of unique contributors
if $DISPLAY_EMAILS; then
echo ""
echo "List of all unique contributors (email addresses) across all scanned repositories:"
echo "--------------------------------------------------"
# Display the unique email addresses
cat "$TEMP_EMAIL_FILE" | sort -u
echo "--------------------------------------------------"
fi
# Clean up the temporary file
rm "$TEMP_EMAIL_FILE"
echo "Script finished."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment