There's a problem that I've seen on every team I've worked with that uses git . Because at Tau Station we're fairly merciless about technical debt--which makes the code base pretty sweet to work with--we take all technical debt issues seriously on the theory that once we launch, it may be too late to clean up (a silly idea in theory, but a prevalent one in practice).

The following technical debt issue is actually causing us a problem, though it's more of a process problem than a technical one:

05:35:02 (master) ~/veure $ git branch -a | wc -l 272

Wow! We have 272 branches? Most of those are are long merged or abandoned. We've discovered that there are a couple of them which got overlooked (I'm tempted to blame github's poor PM tooling, but it's a lousy craftsman who blames his tools). We tried asking devs to find all of their remote branches and review them and delete them, but that turned out to be a rather daunting task and they're still missing branches.

Now, with a simple Perl script, we have a solution.

The following is named branch-authors (many thanks to friends on Twitter who answered my initial git question):

#!/usr/bin/env perl use 5.24.0; use warnings; use Term::ANSIColor; chomp( my @branches = qx/git show -s --pretty='%cn|%ci %D' \$(git rev-parse --branches --remotes)/ ); my %branches_for; for my $branch (@branches) { my ( $author, $branch_info ) = split /\|/ => $branch, 2; push @{ $branches_for{$author} //= [] } => $branch_info; } my @authors = sort keys %branches_for; my $author; do { my $current = 1; foreach (@authors) { say "[$current] $_"; $current++; } $current--; print "Choose an author ('q' to quit): "; chomp( my $response = <STDIN> ); if ( $response =~ /^([0-9]+)$/ ) { if ( $response < 1 || $response > $current ) { say colored(['bright_red on_black'], "Response '$response' is out of range"); } else { $author = $authors[ $response - 1 ]; } } elsif ( $response =~ /^\s*[qQ]/ ) { exit; } else { say colored(['bright_red on_black'], "Please enter an integer from 1 to $current"); } } while not $author; my $branches = $branches_for{$author}; # due to iso date format, we sort on dates for free foreach my $branch (sort @$branches) { say $branch; } __END__ =head1 NAME branch-authors =head1 SYNOPSIS perl bin/branch-authors =head1 DESCRIPTION Prints a list of branch authors and prompts you to choose one. Once chosen, displays a list of all branches believed to be pushed by them, along with the date. This should allow you to easily track down your remote branches and remove them after they've been merged. The syntax for deleting a remote branch is: git push origin :branchname Note that there is a space after C<origin>. This does not delete your local copy. See also: http://gitready.com/beginner/2009/02/02/push-and-delete-branches.html =head1 BRANCH DETECTIONS Currently we guess that the name on the last commit is the person responsible for a given branch. It's up to them to verify that a branch may be safely deleted.

It's a hack, but running the script has an output like this:

[1] Alice [2] Bob [3] Charlie [4] Ovid Choose an author ('q' to quit):

You choose the number of the author in question and you get a full list of all branches found for them, listed from oldest to newest. Here's a truncated list for me:

2016-08-26 12:58:04 +0200 cleanup-666 2016-11-03 15:36:17 +0100 origin/tasks-to-actions-1205 2016-11-09 16:29:08 +0100 origin/character-impairment-1227 2016-11-18 11:33:08 +0100 average-stats-per-level-827 2016-11-20 08:28:52 +0100 origin/average-stats-per-level-827 2016-11-20 17:25:48 +0100 HEAD -> master, origin/master, origin/HEAD