Created
August 20, 2014 16:30
-
-
Save mwerner/7900c655e9de0b40c37c to your computer and use it in GitHub Desktop.
git-clean
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env ruby | |
require 'rubygems' | |
require 'time' | |
require 'colorize' | |
require 'action_view' | |
require 'highline/import' | |
include ActionView::Helpers::DateHelper | |
include ActionView::Helpers::TextHelper | |
I18n.enforce_available_locales = false | |
action = ARGV[0] | |
term = ARGV[1] | |
origin = `git remote show -n origin | grep "Fetch URL:"`.match(/.*\:(.*)\./)[1] | |
sanitize = "grep -v master | sed \"s/ *origin\\///\" | sed \"s/ *tddium\\///\"" | |
sanitize = "grep #{term} | #{sanitize}" unless term.nil? | |
branches = `git branch -r | #{sanitize}`.split("\n").uniq | |
merged = `git branch -r --merged master | #{sanitize}`.split("\n").uniq | |
unmerged = branches - merged | |
## Methods | |
def delete_branch(name) | |
print '!'.red | |
puts " Deleting: #{name}" | |
`git push origin :#{name}` | |
puts "Success!".green | |
end | |
def age_color(time) | |
return :red if time < Time.now - 4 * 7 * 24 * 60 * 60 # five weeks | |
return :light_yellow if time < Time.now - 1 * 7 * 24 * 60 * 60 # one week | |
return :green | |
end | |
def branch_info(name, origin) | |
info = {name: name, origin: origin, commits: {}, age: Time.now}; sha = nil | |
details = `git whatchanged --abbrev-commit master.. origin/#{name}` | |
details.split("\n").each do |line| | |
next if line.nil? || line == '' | |
checks = { name: 'commit', regex: /^commit\s(.*)/ }, | |
{ name: 'author', regex: /^Author:\s(.*)\s</ }, | |
{ name: 'timestamp', regex: /^Date:\s*(.*)$/ }, | |
{ name: 'file', regex: /^:.*\s(.*)/ } | |
checks.each do |check| | |
val = line.match(check[:regex]) | |
next if val.nil? | |
case check[:name].to_sym | |
when :commit | |
sha = val[1] | |
info[:commits][sha] ||= [] | |
when :author | |
info[:author] = val[1] | |
when :file | |
info[:commits][sha] << val[1] unless sha.nil? | |
when :timestamp | |
committed_at = Time.parse(val[1]) | |
info[:age] = committed_at if committed_at < info[:age] | |
end | |
end | |
end | |
info | |
end | |
def print_info(info) | |
files = info[:commits].values.flatten.uniq | |
puts "\n#{info[:name]}".send(age_color(info[:age])) | |
puts " #{info[:author]}" | |
puts " #{pluralize(info[:commits].keys.length, 'commit')} - #{distance_of_time_in_words_to_now(info[:age])} ago" | |
puts " #{files.first(5).join("\n ")}".light_black | |
if files.length > 5 | |
puts " ...".light_black | |
puts " and #{files.length - 5} more...".light_black | |
end | |
puts " https://github.com/#{info[:origin]}/compare/#{info[:branch]}" | |
end | |
## Script | |
## Action: Status | |
if action == 'status' | |
print "Searching remote branches" | |
puts term.nil? ? ':' : " for \"#{term}\":" | |
if merged.length == 0 | |
puts "\n> All remote branches that are merged have been deleted".green | |
else | |
puts "#{pluralize(merged.length, 'branch')} merged into master:".cyan | |
puts " #{merged.join("\n ")}" | |
end | |
if unmerged.length == 0 | |
puts "\n> All unmerged remote branches have been deleted".green | |
else | |
puts "\n#{pluralize(unmerged.length, 'branch')} not been merged into master:".cyan | |
unmerged.each do |branch| | |
info = branch_info(branch, origin) | |
puts " #{info[:name].send(age_color(info[:age]))}" | |
end | |
end | |
exit | |
end | |
## Action: List ( default ) | |
## List any outstanding merged branches | |
if action == 'list' || action.nil? | |
print "Searching remote branches" | |
puts term.nil? ? ':' : " for \"#{term}\":" | |
if merged.length == 0 | |
puts "\n> All remote branches that are merged have been deleted".green | |
else | |
puts "#{pluralize(merged.length, 'branch')} merged into master:".green | |
puts " #{merged.join("\n ")}" | |
choice = ask("Delete all #{merged.length} branches? |(y)es, (n)o, (q)uit|".cyan) | |
exit if choice.strip == 'q' | |
merged.each{|branch| delete_branch(branch) } if choice.strip == 'y' | |
end | |
## Iterate through each outstanding unmerged branches | |
if unmerged.length == 0 | |
puts "\n> All unmerged remote branches have been deleted".green | |
else | |
puts "\n#{pluralize(unmerged.length, 'branch')} not merged:" | |
print "RED ".red | |
puts " - Over a month old" | |
print "YELLOW".light_yellow | |
puts " - Over a week old" | |
print "GREEN ".green | |
puts " - Created this week" | |
unmerged.each do |branch| | |
print_info branch_info(branch, origin) | |
response = ask("Delete #{branch}? |(y)es, (n)o, (q)uit|".cyan) | |
exit if response.strip == 'q' | |
delete_branch(branch) if response.strip == 'y' | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment