Skip to content

Instantly share code, notes, and snippets.

@vorporeal
Created April 15, 2022 18:44
Show Gist options
  • Save vorporeal/87d4127190897f214df0c55949bf8da1 to your computer and use it in GitHub Desktop.
Save vorporeal/87d4127190897f214df0c55949bf8da1 to your computer and use it in GitHub Desktop.
Prune local branches that were merged into a remote GitHub repo using squash commits.
#!/bin/bash
# This script looks for local branches which have an upstream branch set, but
# where said upstream branch no longer exists. The implication here is that the
# engineer pushed the branch to GitHub (to send a PR for review), merged the PR,
# and (auto-)deleted the remote branch.
#
# The script asks for confirmation before deleting the local branches as this is
# destructive, and could cause someone to lose work if a branch gets into this
# state without its contents actually having been merged upstream.
to_delete=""
for branch in $(git branch); do
if [[ "$branch" = "*" ]]; then
continue
fi
# Get the ref name for the branch.
ref=$(git rev-parse --symbolic-full-name $branch)
# Check if there is an upstream branch. If not, it's likely a PR has not been
# created for this branch yet.
upstream=$(git for-each-ref --format='%(upstream:short)' $ref)
if [[ -z "$upstream" ]]; then
continue
fi
# Query the remote for the upstream branch. If it no longer exists, this is
# probably the local branch for a PR that was merged upstream.
remote_branch=$(git ls-remote --heads origin $ref)
if [[ -z "$remote_branch" ]]; then
to_delete="$to_delete $branch"
fi
done
if [[ -z "$to_delete" ]]; then
echo "No local branches need pruning."
else
echo "Found local branches to prune: "
echo ""
for branch in $(echo ${to_delete}); do
echo " $branch"
done
echo ""
# Ask the user for confirmation before taking an action.
read -p "Do you want to delete these local branches? (y/N) " -r
echo ""
if [[ $REPLY =~ ^([Yy]|YES|yes)$ ]]; then
# The user said yes, so forcibly delete the local branches in question.
git branch -D $to_delete
retval=$?
echo ""
if [[ $retval -eq 0 ]]; then
echo "Branches deleted."
else
echo "One or more errors occurred while trying to delete branches."
echo "Some of the listed branches may have been deleted; please consult stderr output."
exit $retval
fi
else
echo "Cancelled."
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment