Skip to content

Instantly share code, notes, and snippets.

@TBonnin
Last active May 27, 2023 14:44
Show Gist options
  • Star 45 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save TBonnin/4060788 to your computer and use it in GitHub Desktop.
Save TBonnin/4060788 to your computer and use it in GitHub Desktop.
Safely remove local fully merged branches
#!/bin/bash
# This has to be run from master
git checkout master
# Update our list of remotes
git fetch
git remote prune origin
# Remove local fully merged branches
git branch --merged master | grep -v 'master$' | xargs git branch -d
# Show remote fully merged branches
echo "The following remote branches are fully merged and will be removed:"
git branch -r --merged master | sed 's/ *origin\///' | grep -v 'master$'
read -p "Continue (y/n)? "
if [ "$REPLY" == "y" ]
then
# Remove remote fully merged branches
git branch -r --merged master | sed 's/ *origin\///' \
| grep -v 'master$' | xargs -I% git push origin :%
echo "Done!"
say "Obsolete branches are removed"
fi
echo "Please, tell your teammates to run 'git remote prune origin' command in order to clean their local repository"
@vackosar
Copy link

We use git-obsolete-branch-remover useful as it lists or removes local or remote Git branches based on last commit date and merge status.
https://github.com/vackosar/git-obsolete-branch-remover

@himdel
Copy link

himdel commented Feb 14, 2019

The script fails when used with more remotes with branches than origin, and assumes master is up to date with upstream, so simplified a bit with that in mind:

#!/bin/bash
set -e

git fetch --all --prune

# Remove local fully merged branches
git branch --merged upstream/master | sed 's/^[ *]\+//' | grep -v '^master$' | xargs -r -d'\n' git branch -D

# Remove origin/ fully merged branches, except for master
git branch --remotes --merged upstream/master | sed 's/^[ *]\+//' | grep '^origin/' | grep -v '/master$' | sed 's/^origin\///' | xargs -r -d'\n' git push --delete origin

git fetch --all --prune

EDIT: added -r to xargs to skip empty lists

@philipbergen
Copy link

@himdel Just a tip to simplify your sed work, you can use any delimiter to avoid escaping, e.g.: sed 's|^origin/||g'

@hartwork
Copy link

If you want to detect squash merges and the likes as well, git-delete-merged-branches may be of interest.

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