Skip to content

Instantly share code, notes, and snippets.

@shevron
Created October 27, 2024 14:27
Show Gist options
  • Save shevron/7d169dfd3b566d516782e46fb3ae23d7 to your computer and use it in GitHub Desktop.
Save shevron/7d169dfd3b566d516782e46fb3ae23d7 to your computer and use it in GitHub Desktop.
Script to list and optionally delete stale Git branches
#!/bin/bash
# Configuration variables
REFERENCE_BRANCH="master" # Branch to compare against
AGE_THRESHOLD_DAYS=180 # Number of days to consider a branch stale
DELETE_BRANCHES=false
CURRENT_DATE=$(date +%s)
if [[ "$(uname)" == "Darwin" ]]; then
DATE_CMD="date -r"
else
DATE_CMD="date -d @"
fi
# Helper function to calculate the difference in days between two dates
days_between() {
local start=$1
local end=$2
echo $(( (end - start) / 86400 ))
}
if [[ "$1" == "--delete" ]]; then
DELETE_BRANCHES=true
echo "Running in delete mode. Identified branches will be deleted."
fi
git fetch --all --prune
remote_branches=$(git branch -r --format='%(refname:short)' | grep -v "$REFERENCE_BRANCH")
for branch in $remote_branches; do
ahead=$(git rev-list --count "$REFERENCE_BRANCH..$branch")
if [ "$ahead" -eq 0 ]; then
last_commit_date=$(git log -1 --format="%ct" "$branch")
branch_age_days=$(days_between "$last_commit_date" "$CURRENT_DATE")
if [ "$branch_age_days" -ge "$AGE_THRESHOLD_DAYS" ]; then
formatted_date=$($DATE_CMD "$last_commit_date" "+%Y-%m-%d %H:%M:%S")
echo "Branch: $branch | Age: $branch_age_days days | Last Commit: $formatted_date"
if [ "$DELETE_BRANCHES" = true ]; then
remote_name=$(echo "$branch" | cut -d'/' -f1)
branch_name=$(echo "$branch" | cut -d'/' -f2-)
# Delete the branch both locally and remotely
echo "Deleting branch $branch_name from remote/$remote_name and local..."
git push "$remote_name" --delete "$branch_name"
git branch -d -r "$branch" || echo "No local tracking branch to delete for $branch."
fi
fi
fi
done
@shevron
Copy link
Author

shevron commented Oct 27, 2024

This will list out all stale Git branches in a repository. By "stale", I mean older than X days (180 by default) and with no commits ahead of the main / master branch.

If run with --delete, these branches will also be deleted from remote and local.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment