Created
October 23, 2025 01:22
-
-
Save anegg0/dfdbfec18a86462940c1ca367472c5b2 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 | |
| # GitHub PR Files Checker | |
| # Shows all files that would appear in a GitHub pull request from the current branch | |
| # Usage: ./pr-files-check.sh [options] | |
| # Options: | |
| # -v, --verbose Show detailed file information including line changes | |
| # -s, --summary Show only summary statistics | |
| # -h, --help Show this help message | |
| set -e | |
| # Colors for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[0;33m' | |
| BLUE='\033[0;34m' | |
| PURPLE='\033[0;35m' | |
| CYAN='\033[0;36m' | |
| WHITE='\033[1;37m' | |
| NC='\033[0m' # No Color | |
| # Default options | |
| VERBOSE=false | |
| SUMMARY_ONLY=false | |
| # Parse command line arguments | |
| while [[ $# -gt 0 ]]; do | |
| case $1 in | |
| -v|--verbose) | |
| VERBOSE=true | |
| shift | |
| ;; | |
| -s|--summary) | |
| SUMMARY_ONLY=true | |
| shift | |
| ;; | |
| -h|--help) | |
| echo "GitHub PR Files Checker" | |
| echo "Usage: $0 [options]" | |
| echo "" | |
| echo "Options:" | |
| echo " -v, --verbose Show detailed file information including line changes" | |
| echo " -s, --summary Show only summary statistics" | |
| echo " -h, --help Show this help message" | |
| echo "" | |
| echo "This script shows all files that would appear in a GitHub pull request" | |
| echo "from the current branch compared to the main/master branch." | |
| exit 0 | |
| ;; | |
| *) | |
| echo "Unknown option: $1" | |
| echo "Use -h or --help for usage information" | |
| exit 1 | |
| ;; | |
| esac | |
| done | |
| # Check if we're in a git repository | |
| if ! git rev-parse --git-dir > /dev/null 2>&1; then | |
| echo -e "${RED}Error: Not in a git repository${NC}" | |
| exit 1 | |
| fi | |
| # Get current branch | |
| CURRENT_BRANCH=$(git branch --show-current) | |
| # Determine the main branch (master or main) | |
| MAIN_BRANCH="" | |
| if git show-ref --verify --quiet refs/heads/master; then | |
| MAIN_BRANCH="master" | |
| elif git show-ref --verify --quiet refs/heads/main; then | |
| MAIN_BRANCH="main" | |
| else | |
| echo -e "${RED}Error: Could not find main or master branch${NC}" | |
| exit 1 | |
| fi | |
| # Check if current branch is the main branch | |
| if [[ "$CURRENT_BRANCH" == "$MAIN_BRANCH" ]]; then | |
| echo -e "${YELLOW}Warning: You are on the main branch ($MAIN_BRANCH)${NC}" | |
| echo "Comparing with HEAD~1 instead..." | |
| MAIN_BRANCH="HEAD~1" | |
| fi | |
| # Ensure we have the latest main branch info | |
| if [[ "$MAIN_BRANCH" != "HEAD~1" ]]; then | |
| git fetch origin "$MAIN_BRANCH" > /dev/null 2>&1 || true | |
| fi | |
| echo -e "${WHITE}=== GitHub PR Files Analysis ===${NC}" | |
| echo -e "${CYAN}Current branch:${NC} $CURRENT_BRANCH" | |
| echo -e "${CYAN}Comparing against:${NC} $MAIN_BRANCH" | |
| echo "" | |
| # Get all files that would be in the PR | |
| FILES_CHANGED=$(git diff --name-status "$MAIN_BRANCH"...HEAD 2>/dev/null || git diff --name-status "$MAIN_BRANCH" HEAD 2>/dev/null || true) | |
| if [[ -z "$FILES_CHANGED" ]]; then | |
| echo -e "${GREEN}No files changed - no PR would be created${NC}" | |
| exit 0 | |
| fi | |
| # Count different types of changes | |
| MODIFIED_COUNT=0 | |
| ADDED_COUNT=0 | |
| DELETED_COUNT=0 | |
| RENAMED_COUNT=0 | |
| COPIED_COUNT=0 | |
| # Arrays to store files by status | |
| declare -a MODIFIED_FILES=() | |
| declare -a ADDED_FILES=() | |
| declare -a DELETED_FILES=() | |
| declare -a RENAMED_FILES=() | |
| declare -a COPIED_FILES=() | |
| # Parse git diff output | |
| while IFS=$'\t' read -r status filename rest; do | |
| case $status in | |
| M*) | |
| MODIFIED_FILES+=("$filename") | |
| ((MODIFIED_COUNT++)) | |
| ;; | |
| A*) | |
| ADDED_FILES+=("$filename") | |
| ((ADDED_COUNT++)) | |
| ;; | |
| D*) | |
| DELETED_FILES+=("$filename") | |
| ((DELETED_COUNT++)) | |
| ;; | |
| R*) | |
| RENAMED_FILES+=("$filename -> $rest") | |
| ((RENAMED_COUNT++)) | |
| ;; | |
| C*) | |
| COPIED_FILES+=("$filename -> $rest") | |
| ((COPIED_COUNT++)) | |
| ;; | |
| esac | |
| done <<< "$FILES_CHANGED" | |
| TOTAL_FILES=$((MODIFIED_COUNT + ADDED_COUNT + DELETED_COUNT + RENAMED_COUNT + COPIED_COUNT)) | |
| # Get commit count | |
| COMMIT_COUNT=$(git rev-list --count "$MAIN_BRANCH"..HEAD 2>/dev/null || git rev-list --count "$MAIN_BRANCH"...HEAD 2>/dev/null || echo "0") | |
| # Get line changes statistics | |
| STATS=$(git diff --shortstat "$MAIN_BRANCH"...HEAD 2>/dev/null || git diff --shortstat "$MAIN_BRANCH" HEAD 2>/dev/null || echo "") | |
| # Summary section | |
| echo -e "${WHITE}=== PR Summary ===${NC}" | |
| echo -e "${PURPLE}Total commits:${NC} $COMMIT_COUNT" | |
| echo -e "${PURPLE}Total files changed:${NC} $TOTAL_FILES" | |
| if [[ -n "$STATS" ]]; then | |
| echo -e "${PURPLE}Line changes:${NC} $STATS" | |
| fi | |
| echo "" | |
| echo -e "${WHITE}=== File Change Breakdown ===${NC}" | |
| if [[ $MODIFIED_COUNT -gt 0 ]]; then | |
| echo -e "${YELLOW}Modified:${NC} $MODIFIED_COUNT files" | |
| fi | |
| if [[ $ADDED_COUNT -gt 0 ]]; then | |
| echo -e "${GREEN}Added:${NC} $ADDED_COUNT files" | |
| fi | |
| if [[ $DELETED_COUNT -gt 0 ]]; then | |
| echo -e "${RED}Deleted:${NC} $DELETED_COUNT files" | |
| fi | |
| if [[ $RENAMED_COUNT -gt 0 ]]; then | |
| echo -e "${BLUE}Renamed:${NC} $RENAMED_COUNT files" | |
| fi | |
| if [[ $COPIED_COUNT -gt 0 ]]; then | |
| echo -e "${CYAN}Copied:${NC} $COPIED_COUNT files" | |
| fi | |
| # If summary only, exit here | |
| if [[ "$SUMMARY_ONLY" == "true" ]]; then | |
| exit 0 | |
| fi | |
| echo "" | |
| # Function to categorize files by type | |
| categorize_file() { | |
| local file="$1" | |
| local ext="${file##*.}" | |
| local basename="${file##*/}" | |
| case "$ext" in | |
| md|mdx) echo "Documentation" ;; | |
| js|jsx|ts|tsx) echo "JavaScript/TypeScript" ;; | |
| py) echo "Python" ;; | |
| yml|yaml) echo "Configuration (YAML)" ;; | |
| json) echo "Configuration (JSON)" ;; | |
| css|scss|sass) echo "Stylesheets" ;; | |
| html|htm) echo "HTML" ;; | |
| sh) echo "Shell Scripts" ;; | |
| *) | |
| case "$basename" in | |
| Dockerfile*) echo "Docker" ;; | |
| *config*) echo "Configuration" ;; | |
| *test*) echo "Tests" ;; | |
| README*|LICENSE*) echo "Documentation" ;; | |
| *) echo "Other" ;; | |
| esac | |
| ;; | |
| esac | |
| } | |
| # Function to show file list with categories | |
| show_file_list() { | |
| local title="$1" | |
| local color="$2" | |
| local -n files_array=$3 | |
| if [[ ${#files_array[@]} -eq 0 ]]; then | |
| return | |
| fi | |
| echo -e "${WHITE}=== $title Files ===${NC}" | |
| # Create associative array for categories | |
| declare -A categories | |
| for file in "${files_array[@]}"; do | |
| # Handle renamed/copied files | |
| local display_file="$file" | |
| local actual_file="$file" | |
| if [[ "$file" == *" -> "* ]]; then | |
| actual_file="${file%% -> *}" | |
| fi | |
| local category=$(categorize_file "$actual_file") | |
| if [[ -z "${categories[$category]}" ]]; then | |
| categories[$category]="$display_file" | |
| else | |
| categories[$category]="${categories[$category]}"$'\n'"$display_file" | |
| fi | |
| done | |
| # Display files grouped by category | |
| for category in $(printf '%s\n' "${!categories[@]}" | sort); do | |
| echo -e "${PURPLE} $category:${NC}" | |
| while IFS= read -r file; do | |
| if [[ "$VERBOSE" == "true" ]] && [[ "$title" == "Modified" ]]; then | |
| # Show line changes for modified files | |
| local changes=$(git diff --numstat "$MAIN_BRANCH"...HEAD -- "$file" 2>/dev/null || git diff --numstat "$MAIN_BRANCH" HEAD -- "$file" 2>/dev/null || echo "- -") | |
| local additions=$(echo "$changes" | cut -f1) | |
| local deletions=$(echo "$changes" | cut -f2) | |
| if [[ "$additions" != "-" ]] && [[ "$deletions" != "-" ]]; then | |
| echo -e " ${color}$file${NC} ${GREEN}(+$additions)${NC} ${RED}(-$deletions)${NC}" | |
| else | |
| echo -e " ${color}$file${NC}" | |
| fi | |
| else | |
| echo -e " ${color}$file${NC}" | |
| fi | |
| done <<< "${categories[$category]}" | |
| done | |
| echo "" | |
| } | |
| # Show file lists | |
| show_file_list "Modified" "$YELLOW" MODIFIED_FILES | |
| show_file_list "Added" "$GREEN" ADDED_FILES | |
| show_file_list "Deleted" "$RED" DELETED_FILES | |
| show_file_list "Renamed" "$BLUE" RENAMED_FILES | |
| show_file_list "Copied" "$CYAN" COPIED_FILES | |
| # Show recent commits that would be in the PR | |
| echo -e "${WHITE}=== Recent Commits (Last 5) ===${NC}" | |
| git log --oneline --graph "$MAIN_BRANCH"..HEAD 2>/dev/null | head -5 || \ | |
| git log --oneline --graph "$MAIN_BRANCH"...HEAD 2>/dev/null | head -5 || \ | |
| echo -e "${YELLOW}Could not retrieve commit history${NC}" | |
| echo "" | |
| echo -e "${WHITE}=== GitHub PR Command ===${NC}" | |
| echo -e "${CYAN}To create a PR using GitHub CLI:${NC}" | |
| echo "gh pr create --title \"Your PR title\" --body \"Your PR description\"" | |
| echo "" | |
| echo -e "${CYAN}To view diff in browser:${NC}" | |
| echo "gh pr create --web" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment