BASH
Clean Up Stale Local Git Branches
A useful bash script to automatically delete local Git branches that have already been merged into the main branch or whose remote tracking branch no longer exists.
#!/bin/bash
# This script cleans up local Git branches that have been merged
# into the current branch (e.g., 'main' or 'master') or whose remote tracking branch no longer exists.
# Set default main branch name
MAIN_BRANCH="main"
# Check if current directory is a git repository
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
echo "Error: Not a Git repository."
exit 1
fi
# Fetch latest remote changes to update local tracking branches
echo "Fetching latest remote changes..."
git fetch --prune
echo "Deleting local branches merged into '$MAIN_BRANCH'...
"
# List merged branches, excluding main/master and currently checked out branch
CURRENT_HEAD=$(git rev-parse --abbrev-ref HEAD)
MERGED_BRANCHES=$(git branch --merged "$MAIN_BRANCH" | grep -v "$MAIN_BRANCH" | grep -v "$CURRENT_HEAD" | sed 's/^\s*//')
if [ -z "$MERGED_BRANCHES" ]; then
echo "No merged branches to delete."
elif [ -n "$MERGED_BRANCHES" ]; then
echo "$MERGED_BRANCHES" | xargs -r git branch -d
echo "Merged branches cleanup complete."
fi
echo "
Deleting local branches whose remote tracking branch no longer exists..."
# Identify and delete stale remote tracking branches
# This command prunes local branches that no longer have a remote counterpart
STALE_REMOTE_TRACKING_BRANCHES=$(git remote prune origin --dry-run | grep 'would prune' | awk '{print $NF}')
if [ -n "$STALE_REMOTE_TRACKING_BRANCHES" ]; then
echo "The following remote tracking branches would be pruned (dry run):"
echo "$STALE_REMOTE_TRACKING_BRANCHES"
read -p "Execute actual prune? (y/N): " -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
git remote prune origin
echo "Stale remote tracking branches pruned."
else
echo "Skipping actual remote prune."
fi
else
echo "No stale remote tracking branches to prune."
fi
echo "
Git cleanup script finished."
How it works: This script first fetches the latest remote changes (`git fetch --prune`) to ensure local tracking branches are up-to-date. It then identifies and deletes local branches that have already been merged into the `main` branch (or `master`, adjusted by user) and are not the currently active branch. Additionally, it helps prune stale remote-tracking branches (e.g., `origin/feature-x`) that no longer exist on the remote, offering a dry-run first for safety. This keeps your local repository tidy and manageable.