Delete stalled git tags and branches

Sometimes when you get new project that is under development for few years you see some obsolete tags and branches in git repo. After you getting approval to clean them up you realize that there are too many of them to be removed manually. In my case about a hundred. Lets see how you can script removing all tags and branches older than 3 months.

Remember to backup your repo before doing all the actions below.

Cleaning up tags

If you work with tags based deployments you probably have a pattern for your tags. In my case we named tags YYYY-MM-DD.X. Here is a list of shell commands to clean up tags:

git tag -l | grep 2012 | xargs -n 1 git push --delete origin
git tag | grep 2012 | xargs git tag -d

These commands delete tags from year 2012 both in remote and local repositories.

After initial cleaning up all old tags, we could set up script that will automatically clean up all tags older than 3 months. Also to get this script running in Jenkins once a month.

git fetch --tags origin
git tag -l | grep `date -d'-3month' +'%Y-%m'` | xargs -n 1 git push --delete origin || true
git tag | grep `date -d'-3month' +'%Y-%m'` | xargs git tag -d

Cleaning up branches

Now lets clean up all git remote branches without activity for 3 months.

First we need to see what branches we should not delete (that have activity in last 3 months. For this I used command:

git for-each-ref --sort=committerdate refs/remotes/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'

Pay attention that we are checking remote branches. Then I built a list of branches I do not want to delete. Make sure you include your HEAD, master branches.

And finally here is command to delete branches from remote repo excluding our list.

git br -a | grep -v -E master\|HEAD\|production\|staging | sed 's/remotes\/origin\//:/g' | xargs git push origin

You'll need to list branches you do not want to delete in 'grep' section separated by '\|'.

Now you should have nice and clean git repo with way less obsolete tags and branches.