Cleanup git branches

Most of the time i develop projects using feature branches and it works great as it provides an isolated workspace that eventually gets merged into master via pull requests or directly. Over time i added a few tricks and tools that make working with multiple branches easier. Some of them are just a simple git aliases, some are ruby/bash scripts.

At some point you'll see a lots of old (merged on unmerged) branches in your git repository, and you'll wonder how behind are they, or whats the difference between master and that branch. Here's the example of a script git branches that i use to check on branches status:

git-branches

And here's the script that provides this capability:

#!/usr/bin/env ruby

class String
  def red    ; colorize(self, "\e[1m\e[31m") ; end
  def green  ; colorize(self, "\e[1m\e[32m") ; end
  def yellow ; colorize(self, "\e[1m\e[33m") ; end

  def colorize(text, color_code)
    "#{color_code}#{text}\e[0m"
  end
end

def diff(num, word)
  color = case num
  when 0..5
    :green
  when 5..15
    :yellow
  else
    :red
  end

  "#{num} #{word}".send(color)
end

unless File.exists?("#{Dir.pwd}/.git")
  puts "Not a git repo"
  exit
end

current = `git rev-parse --abbrev-ref HEAD`.strip
all     = `git branch --list --no-color`.strip.split("\n").reject { |n| n =~ /^\*/ }.map(&:strip)

if all.empty?
  puts "Nothing to compare..."
  exit
end

pad = all.sort { |a,b| b.size <=> a.size }.first.size

puts
all.each do |name|
  behind = `git rev-list #{name}..#{current}`.strip.split("\n").size
  ahead  = `git rev-list #{current}..#{name}`.strip.split("\n").size
  puts "#{name.rjust(pad)} - #{diff(behind, "behind")}, #{diff(ahead, "ahead")}"
end
puts

Instead of removing branches by hand you can create a bash script git clean-merged, with the following content:

git branch --merged | grep -v "\*" | xargs -n 1 git branch -d

Most of the scipts and aliases i keep in dotfiles. Checkout my github repository