Created
June 21, 2025 04:34
-
-
Save mikegwhit/b7eebcd868acb8655f539e47f771347e to your computer and use it in GitHub Desktop.
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 | |
# git-diff-json.sh - Get Git diff information in JSON format | |
# | |
# Usage: | |
# ./git-diff-json.sh [directory] [options] | |
# | |
# Options: | |
# --compare-branch, -c Branch to compare against (default: main) | |
# --no-local-changes, -n Don't include local changes in comparison | |
# --name-only Return only file names instead of full diff | |
# --summary, -s Return only summary of changes | |
# --output, -o Output file (default: .git-diff.json in CWD) | |
# --help, -h Show this help message | |
# Default values | |
COMPARE_BRANCH="main" | |
INCLUDE_LOCAL_CHANGES=true | |
NAME_ONLY=false | |
SUMMARY=false | |
OUTPUT_FILE="" | |
DIRECTORY="$(pwd)" | |
# Function to show help | |
show_help() { | |
grep '^#' "$0" | grep -v '#!/bin/bash' | sed 's/^# \?//' | |
exit 0 | |
} | |
# Parse arguments | |
while [[ $# -gt 0 ]]; do | |
case "$1" in | |
--compare-branch|-c) | |
COMPARE_BRANCH="$2" | |
shift 2 | |
;; | |
--no-local-changes|-n) | |
INCLUDE_LOCAL_CHANGES=false | |
shift | |
;; | |
--name-only) | |
NAME_ONLY=true | |
shift | |
;; | |
--summary|-s) | |
SUMMARY=true | |
shift | |
;; | |
--output|-o) | |
OUTPUT_FILE="$2" | |
shift 2 | |
;; | |
--help|-h) | |
show_help | |
;; | |
*) | |
# If the argument doesn't start with a dash, treat it as a directory | |
if [[ ! "$1" =~ ^- ]]; then | |
DIRECTORY="$1" | |
else | |
echo "Unknown option: $1" | |
exit 1 | |
fi | |
shift | |
;; | |
esac | |
done | |
# Set default output file if not specified | |
if [ -z "$OUTPUT_FILE" ]; then | |
OUTPUT_FILE="$DIRECTORY/.git-diff.json" | |
fi | |
# Check if directory exists and is a git repository | |
if [ ! -d "$DIRECTORY" ]; then | |
echo "Error: Directory '$DIRECTORY' does not exist" >&2 | |
exit 1 | |
fi | |
# Save current directory to return to it later | |
ORIGINAL_DIR=$(pwd) | |
# Move to the specified directory | |
cd "$DIRECTORY" || { echo "Error: Cannot change to directory '$DIRECTORY'" >&2; exit 1; } | |
# Check if this is a git repository | |
if ! git rev-parse --git-dir > /dev/null 2>&1; then | |
echo "Error: Not a git repository: '$DIRECTORY'" >&2 | |
cd "$ORIGINAL_DIR" | |
exit 1 | |
fi | |
# Get current branch | |
CURRENT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse HEAD) | |
# Build diff command options | |
DIFF_OPTIONS="" | |
if [ "$NAME_ONLY" = true ]; then | |
DIFF_OPTIONS="$DIFF_OPTIONS --name-only" | |
fi | |
if [ "$SUMMARY" = true ]; then | |
DIFF_OPTIONS="$DIFF_OPTIONS --stat" | |
fi | |
# Get diff result based on options | |
if [ "$INCLUDE_LOCAL_CHANGES" = true ]; then | |
# Compare working tree to specified branch | |
DIFF_RESULT=$(git diff $DIFF_OPTIONS "$COMPARE_BRANCH") | |
DIFF_MODE="local-to-branch" | |
else | |
# Compare current branch to specified branch without local changes | |
DIFF_RESULT=$(git diff $DIFF_OPTIONS "${COMPARE_BRANCH}...${CURRENT_BRANCH}") | |
DIFF_MODE="branch-to-branch" | |
fi | |
# Get repository information | |
REPO_DIR=$(git rev-parse --show-toplevel) | |
REPO_NAME=$(basename "$REPO_DIR") | |
REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "") | |
# Create JSON output | |
# Escape JSON special characters | |
DIFF_RESULT_ESCAPED=$(echo "$DIFF_RESULT" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed 's/\n/\\n/g' | tr -d '\r') | |
JSON_OUTPUT="{ | |
\"repository\": \"$REPO_NAME\", | |
\"directory\": \"$REPO_DIR\", | |
\"remote\": \"$REMOTE_URL\", | |
\"currentBranch\": \"$CURRENT_BRANCH\", | |
\"compareBranch\": \"$COMPARE_BRANCH\", | |
\"mode\": \"$DIFF_MODE\", | |
\"includeLocalChanges\": $INCLUDE_LOCAL_CHANGES, | |
\"timestamp\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\", | |
\"diff\": \"$DIFF_RESULT_ESCAPED\" | |
}" | |
# Output JSON | |
if [ -z "$OUTPUT_FILE" ] || [ "$OUTPUT_FILE" = "-" ]; then | |
echo "$JSON_OUTPUT" | |
else | |
echo "$JSON_OUTPUT" > "$OUTPUT_FILE" | |
echo "Diff information saved to $OUTPUT_FILE" | |
fi | |
# Return to original directory | |
cd "$ORIGINAL_DIR" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment