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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs