Created
March 15, 2026 23:36
-
-
Save e0da/971b6cb85008dd8a19861c4f83be5f21 to your computer and use it in GitHub Desktop.
Gource wrapper for visualizing multiple repositories
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash -e | |
| # Gource wrapper for visualizing multiple repositories | |
| # Based on: https://github.com/acaudwell/Gource/wiki/Visualizing-Multiple-Repositories | |
| if [ -n "$DEBUG" ]; then | |
| set -x | |
| echo '$*:' "$*" | |
| echo '$@:' "$@" | |
| echo '$#:' "$#" | |
| echo '$?:' "$?" | |
| fi | |
| usage=" | |
| gources: Visualize multiple git repositories with Gource | |
| Usage: | |
| gources [options] <repo1> [repo2] [repo3] ... | |
| Arguments: | |
| repo1, repo2, ... Git repository names/directories to visualize | |
| Options: | |
| -h, --help Show this help message and exit | |
| -o, --output FILE Output combined log to FILE instead of running gource | |
| --no-separate Don't separate repositories into different directory trees | |
| --gource-opts OPTS Pass additional options to gource (quote them) | |
| Examples: | |
| gources myproject otherproject | |
| gources --no-separate frontend backend api | |
| gources -o combined.log repo1 repo2 repo3 | |
| gources --gource-opts '--hide-root --seconds-per-day 0.1' app lib | |
| " | |
| # Parse arguments | |
| output_file="" | |
| separate_repos=true | |
| gource_opts="" | |
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| -h|--help) | |
| echo "$usage" | |
| exit 0 | |
| ;; | |
| -o|--output) | |
| output_file="$2" | |
| shift 2 | |
| ;; | |
| --no-separate) | |
| separate_repos=false | |
| shift | |
| ;; | |
| --gource-opts) | |
| gource_opts="$2" | |
| shift 2 | |
| ;; | |
| -*) | |
| echo "Unknown option: $1" >&2 | |
| echo "$usage" >&2 | |
| exit 1 | |
| ;; | |
| *) | |
| # Repository arguments | |
| break | |
| ;; | |
| esac | |
| done | |
| # Check if we have repositories to process | |
| if [ $# -eq 0 ]; then | |
| echo "Error: No repositories specified" >&2 | |
| echo "$usage" >&2 | |
| exit 1 | |
| fi | |
| # Check if gource is available | |
| if ! command -v gource >/dev/null 2>&1; then | |
| echo "Error: gource is not installed. Please install it first." >&2 | |
| echo "On macOS: brew install gource" >&2 | |
| echo "On Ubuntu/Debian: apt-get install gource" >&2 | |
| exit 1 | |
| fi | |
| # Create temporary directory for log files | |
| temp_dir=$(mktemp -d) | |
| trap "rm -rf '$temp_dir'" EXIT | |
| combined_log="$temp_dir/combined.txt" | |
| # Process each repository | |
| for repo in "$@"; do | |
| if [ ! -d "$repo" ]; then | |
| echo "Warning: Repository '$repo' does not exist, skipping" >&2 | |
| continue | |
| fi | |
| if [ ! -d "$repo/.git" ]; then | |
| echo "Warning: '$repo' is not a git repository, skipping" >&2 | |
| continue | |
| fi | |
| echo "Processing repository: $repo" >&2 | |
| # Generate custom log for this repository | |
| # Use a sanitized name for the log file to avoid issues with special characters | |
| repo_name=$(basename "$repo" | sed 's/[^a-zA-Z0-9._-]/_/g') | |
| [ "$repo_name" = "." ] && repo_name="current_directory" | |
| repo_log="$temp_dir/${repo_name}.txt" | |
| gource --output-custom-log "$repo_log" "$repo" | |
| # Add repository name as parent directory if separating repos | |
| if [ "$separate_repos" = true ]; then | |
| if command -v gsed >/dev/null 2>&1; then | |
| # Use GNU sed if available (Linux) | |
| gsed -i -r "s#(.+)\|#\1|/$repo#" "$repo_log" | |
| else | |
| # Use macOS sed (BSD sed) | |
| sed -i '' -E "s#(.+)\|#\\1|/$repo#" "$repo_log" | |
| fi | |
| fi | |
| done | |
| # Combine all logs and sort by timestamp | |
| cat "$temp_dir"/*.txt 2>/dev/null | sort -n > "$combined_log" | |
| # Check if we got any data | |
| if [ ! -s "$combined_log" ]; then | |
| echo "Error: No valid git repositories found or no commits to visualize" >&2 | |
| exit 1 | |
| fi | |
| # Either output to file or run gource | |
| if [ -n "$output_file" ]; then | |
| cp "$combined_log" "$output_file" | |
| echo "Combined log saved to: $output_file" >&2 | |
| else | |
| echo "Starting Gource visualization..." >&2 | |
| # shellcheck disable=SC2086 | |
| exec gource $gource_opts "$combined_log" | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment