Skip to content

Instantly share code, notes, and snippets.

@skwid138
Created January 8, 2025 17:20
Show Gist options
  • Save skwid138/594343e5f46f0b02d88d78e9349a12ed to your computer and use it in GitHub Desktop.
Save skwid138/594343e5f46f0b02d88d78e9349a12ed to your computer and use it in GitHub Desktop.
Compare branches in a Git repository, detect merge conflicts, and display detailed outputs with options for verbosity and branch customization.
#!/bin/bash
# Default values
base_branch=""
compare_branch=""
verbose=false
compare_all=false
# Help documentation
usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " --base, -b Specify the base branch to compare against (default: origin/develop, origin/main)"
echo " --compare, -c Specify the branch to compare with the base branch (default: current branch)"
echo " --all, -a Compare the base branch against all active branches"
echo " --verbose, -v Show detailed output including conflicting file paths"
echo " --help, -h Display this help message"
echo ""
echo "Description:"
echo "This script compares the number of commits and detects conflicts between a base branch"
echo "and other branches in the current Git repository."
echo ""
echo "Examples:"
echo " Compare current branch with develop/main: $0"
echo " Compare base branch with all active branches: $0 -a"
echo " Compare specific branches with detailed output: $0 -b develop -c feature-branch -v"
echo ""
exit 0
}
# Parse arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--base | -b)
base_branch="$2"
shift 2
;;
--compare | -c)
compare_branch="$2"
shift 2
;;
--all | -a)
compare_all=true
shift
;;
--verbose | -v)
verbose=true
shift
;;
--help | -h)
usage
;;
*)
echo "Unknown option: $1"
usage
;;
esac
done
# Check if we're in a Git repository
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "Error: Not inside a Git repository." >&2
exit 1
fi
# Determine the base branch if not explicitly set
if [[ -z "$base_branch" ]]; then
echo "Determining the base branch..."
if git show-ref --verify --quiet refs/remotes/origin/develop; then
base_branch="origin/develop"
elif git show-ref --verify --quiet refs/remotes/origin/main; then
base_branch="origin/main"
else
echo "Error: No default base branch found. This repository doesn't have 'origin/develop' or 'origin/main'."
echo "Please specify a base branch explicitly using --base or -b."
exit 1
fi
fi
# Get the current branch if compare branch is not provided and not using --all
if [[ -z "$compare_branch" && "$compare_all" == false ]]; then
compare_branch=$(git rev-parse --abbrev-ref HEAD)
fi
# Ensure you have the latest changes before comparing
echo "Fetching latest changes..."
git fetch --all
# Function to check conflicts between branches
check_conflicts() {
local base=$1
local compare=$2
echo "Comparing $base to $compare..."
behind_ahead=$(git rev-list --left-right --count "$base...$compare" 2>/dev/null)
if [[ $? -ne 0 ]]; then
echo "Error: Failed to compare $base and $compare. Ensure both branches exist."
return
fi
behind=$(echo "$behind_ahead" | awk '{print $1}')
ahead=$(echo "$behind_ahead" | awk '{print $2}')
echo "Behind $base by: $behind commits"
echo "Ahead of $base by: $ahead commits"
# Check for conflicts
conflicts=$(git merge-tree $(git merge-base $base $compare) $base $compare | grep '^<<<<<<< ')
if [[ -n "$conflicts" ]]; then
echo "Conflict Detected on $compare in $(echo "$conflicts" | wc -l) files"
if [[ "$verbose" == true ]]; then
echo "Conflicts:"
echo "$conflicts"
fi
else
echo "No conflicts detected on $compare."
fi
}
# Compare all branches if --all is specified
if [[ "$compare_all" == true ]]; then
branches=$(git branch -r | grep -v "$base_branch" | grep -v "HEAD")
total_branches=$(echo "$branches" | wc -l) # Count the total branches
count=0
for branch in $branches; do
((count++))
check_conflicts "$base_branch" "$branch"
# Add a divider only if it's not the last branch
if [[ $count -lt $total_branches ]]; then
echo
echo "----------------------------------------"
echo
fi
done
else
# Compare specified or default branches
check_conflicts "$base_branch" "$compare_branch"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment