# Git Diff Helper Scripts This directory contains bash utility scripts for git diff operations used by the get-git-diff skill. ## Scripts Overview ### validate.sh Validation and verification functions. **Functions:** - `is_git_repo()` - Check if in a git repository - `validate_commit ` - Validate a commit reference - `validate_commit_pair ` - Validate two commits **Usage:** ```bash source validate.sh if is_git_repo; then validate_commit "HEAD" fi ``` ### commit_info.sh Commit information and metadata retrieval. **Functions:** - `get_commit_info ` - Get full commit information - `get_short_hash ` - Get 7-character hash - `is_merge_commit ` - Check if merge commit - `get_commits_between ` - Count commits between refs - `get_commit_message ` - Get commit message - `get_commit_author ` - Get commit author - `get_commit_date ` - Get commit date **Usage:** ```bash source commit_info.sh info=$(get_commit_info "HEAD") IFS='|' read -r full short author email date message <<< "$info" echo "Commit: $short - $message" ``` ### diff_stats.sh Diff statistics and analysis. **Functions:** - `get_diff_stats ` - Get diff statistics - `get_file_stats ` - Get per-file statistics - `is_large_diff [threshold]` - Check if diff is large - `get_total_lines ` - Get total lines changed - `get_files_changed ` - Get file count **Usage:** ```bash source diff_stats.sh stats=$(get_diff_stats "HEAD^" "HEAD") IFS=$'\t' read -r files ins del net <<< "$stats" echo "Changed: $files files, +$ins -$del" ``` ### file_operations.sh File operation analysis (add, modify, delete, rename). **Functions:** - `get_file_operations ` - Get file operations - `count_file_operations ` - Count operations by type - `get_files_by_operation ` - Filter by operation (A/M/D/R) - `get_renamed_files ` - Get renames with similarity - `get_binary_files ` - Get binary files - `count_binary_files ` - Count binary files - `categorize_files` - Categorize files by type (reads from stdin) - `get_categorized_counts ` - Get category counts **Usage:** ```bash source file_operations.sh counts=$(count_file_operations "main" "feature-branch") IFS=$'\t' read -r added modified deleted renamed copied <<< "$counts" echo "Added: $added, Modified: $modified" ``` ### utils.sh General utility functions. **Functions:** - `get_current_branch()` - Get current branch name - `get_default_branch()` - Get default branch (main/master) - `format_diff_filename ` - Format output filename - `get_repo_root()` - Get repository root path - `get_repo_name()` - Get repository name - `get_remote_url [remote]` - Get remote URL - `is_ancestor ` - Check if ref1 is ancestor of ref2 - `get_common_ancestor ` - Get merge base - `format_timestamp [format]` - Format current timestamp - `ensure_directory ` - Create directory if needed - `get_git_config ` - Get git config value - `is_working_tree_clean()` - Check for uncommitted changes - `get_branches [type]` - List branches (local/remote/all) - `ref_exists ` - Check if ref exists **Usage:** ```bash source utils.sh branch=$(get_current_branch) filename=$(format_diff_filename "abc123" "def456") ``` ## Running Scripts Directly All scripts can be sourced for their functions or run directly for examples: ```bash # Run directly for examples ./commit_info.sh HEAD ./diff_stats.sh HEAD^ HEAD ./file_operations.sh main feature-branch ./utils.sh # Source for functions source diff_stats.sh if is_large_diff "HEAD^" "HEAD" 500; then echo "Large diff detected!" fi ``` ## Complete Example ```bash #!/usr/bin/env bash # Source all helper scripts SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" source "${SCRIPT_DIR}/validate.sh" source "${SCRIPT_DIR}/commit_info.sh" source "${SCRIPT_DIR}/diff_stats.sh" source "${SCRIPT_DIR}/file_operations.sh" source "${SCRIPT_DIR}/utils.sh" # Validate we're in a git repo if ! is_git_repo; then echo "Error: Not in a git repository" exit 1 fi # Get commits to compare commit1="HEAD^" commit2="HEAD" # Validate commits if ! validate_commit_pair "$commit1" "$commit2" >/dev/null; then echo "Error: Invalid commits" exit 1 fi # Get commit info info1=$(get_commit_info "$commit1") info2=$(get_commit_info "$commit2") IFS='|' read -r _ short1 _ _ _ msg1 <<< "$info1" IFS='|' read -r _ short2 _ _ _ msg2 <<< "$info2" echo "Comparing: $short1 → $short2" # Get statistics stats=$(get_diff_stats "$commit1" "$commit2") IFS=$'\t' read -r files ins del net <<< "$stats" echo "Files: $files" echo "Changes: +$ins -$del (net: $net)" # Check if large if is_large_diff "$commit1" "$commit2"; then total=$(is_large_diff "$commit1" "$commit2") echo "⚠ Large diff: $total lines" fi # File operations ops=$(count_file_operations "$commit1" "$commit2") IFS=$'\t' read -r added modified deleted renamed _ <<< "$ops" echo "Added: $added, Modified: $modified" if [[ $renamed -gt 0 ]]; then echo "Renamed files:" get_renamed_files "$commit1" "$commit2" | while IFS=$'\t' read -r sim old new; do echo " $old → $new ($sim%)" done fi # Generate filename filename=$(format_diff_filename "$short1" "$short2") echo "Output: $filename" ``` ## Error Handling All scripts use `set -euo pipefail` for strict error handling: - `-e`: Exit on error - `-u`: Exit on undefined variable - `-o pipefail`: Fail on pipe errors When sourcing, you may want to disable this: ```bash set +euo pipefail source diff_stats.sh set -euo pipefail ``` ## Dependencies - bash 4.0+ - git 2.0+ - Standard Unix utilities (awk, sed, cut, wc) ## Testing Each script includes a main section that runs when executed directly: ```bash # Test all scripts ./validate.sh HEAD ./commit_info.sh HEAD HEAD^ ./diff_stats.sh HEAD^ HEAD ./file_operations.sh HEAD^ HEAD ./utils.sh ``` ## Integration with Skill These scripts are designed to be used by Claude Code when executing the get-git-diff skill. They provide reliable, composable functions for git diff analysis. Example integration: ```bash # In skill execution source scripts/validate.sh source scripts/diff_stats.sh if validate_commit "$user_commit"; then stats=$(get_diff_stats "$user_commit" "HEAD") # Process stats... fi ```