Friday, January 9, 2015

Spring cleaning of git branches

It's time to clean out some old branches from the team's git repository. In memory of them, I record useful tricks here.

First, Sharon's post talks about finding branches that are ripe for deletion, by detecting branches already merged. This post covers those, plus how to find out more about the others. This post is concerned with removing unused branches from origin, not locally.

Here's a useful hint: start with
git fetch -p
to update your local repository with what's in origin, including noticing which branches have been deleted from origin.
Also, don't forget to
git checkout mastergit merge --ff-only
so that you'll be on the master branch, up-to-date with origin (and won't accidentally create a merge commit if you have local changes).

Next, to find branches already merged to master:

git branch -a --merged

This lists branches, including remote branches (the ones on origin), but only ones already merged to the current branch. Note that the argument order is important; the reverse gives a silly error.  Here's a one-liner that lists them:
git branch -a --merged | grep -v -e HEAD -e master | grep origin | cut -d '/' -f 3- 
This says, find branches already merged; exclude any references to master and HEAD; include only ones from origin (hopefully); cut out the /remotes/origin/ prefix.

The listed branches are safe to delete. If you're brave, delete them permanently from origin by adding this to the previous command:
 | xargs git push --delete origin
This says, take all those words and put them at the end of this other command, which says "delete these references on the origin repository."

OK, those were the easy ones. What about all the branches that haven't been merged? Who created those things anyway, and how old are they?

git log --date=iso --pretty=format:"%an %ad %d" -1 --decorate

is a lovely command that lists the author, date in ISO format (which is good for sorting), and branches and tags of the last commit (on the current branch, by default).

Use it on all the branches on origin:
git branch -a | grep origin | grep -v HEAD | xargs -n 1 git log --date=iso --pretty=format:"%an %ad %d%n" -1 --decorate | grep -v master | sort
List remote branches; only the ones from origin; exclude the HEAD, we don't care and that line is formatted oddly; send each one through the handy description; exclude master; sort (by name then date, since that's the information at the beginning of the line).

This gives me a bunch of lines that look like:

Shashy 2014-08-15 11:07:37 -0400  (origin/faster-upsert)
Shashy 2014-10-23 22:11:40 -0400  (origin/fix_planners)
Shashy 2014-11-30 06:50:57 -0500  (origin/remote-upsert)
Tanya 2014-10-24 11:35:02 -0500  (origin/tanya_jess/newrelic)
Tanya 2014-11-13 10:04:48 -0600  (origin/kafka)
Yves Dorfsman 2014-04-24 14:43:04 -0600  (origin/data_service)
clinton 2014-07-31 16:26:37 -0600  (origin/warrifying)
clinton 2014-09-15 13:29:14 -0600  (origin/tomcat-treats)

Now I am equipped to email those people and ask them to please delete their stray branches, or give me permission to delete them.

1 comment: