Last active
August 31, 2021 16:00
-
-
Save midwire/0b4ece1d6e8a548dfc1f081a5b5cd67c to your computer and use it in GitHub Desktop.
Revisions
-
midwire revised this gist
Aug 16, 2016 . No changes.There are no files selected for viewing
-
midwire revised this gist
Aug 16, 2016 . No changes.There are no files selected for viewing
-
midwire created this gist
Aug 16, 2016 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,142 @@ #!/usr/bin/env ruby # # Get a list of merged branches # # You need to checkout the target remote branch before running. In other words, # if your target branch is 'master', you have to have it checked out before you # run this script, otherwise you will get an error like: `fatal: malformed # object name master`. Git needs to have the branch checked out in order to find # the branches that have/have-not been merged into it. # # To create a list of branch-names only, without date info # # git-merged-branches.rb --branch production --exclude-days 180 | cut -f1 -d'|' # # For help run: git-merged-branches.rb --help require 'trollop' require 'fileutils' require 'colored' class GitMergedBranches attr_accessor :branch_count, :options, :elapsed, :excluded_branches, :matched_count include FileUtils class BranchEntry attr_accessor :name, :last_commit_date, :relative_last_commit def initialize(name, last_commit_date, relative_last_commit) self.name = name self.last_commit_date = last_commit_date self.relative_last_commit = relative_last_commit end def <=>(other) self.last_commit_date <=> other.last_commit_date end def to_s "#{name} | #{last_commit_date} | #{relative_last_commit}" end end class << self def collect_args(*_args) opts = Trollop.options do opt( :branch, 'Base branch - list branches merged into this branch. Uses current branch if not specified.', type: :string, short: 'b', required: false ) opt( :exclude_days, 'Exclude branches that have no commits within this many days', type: :integer, short: 'x', required: false, default: 0 ) opt( :color, 'Use colored output', type: :boolean, short: 'c', required: false, default: true ) end # Set branch to current if not given on command line opts[:branch] ||= `git rev-parse --abbrev-ref HEAD`.chomp opts end def run start_time = Time.now opts = collect_args(ARGV) instance = GitMergedBranches.new(opts) instance.process instance.elapsed = Time.now - start_time instance.report_summary end end def initialize(opts) self.branch_count = 0 self.excluded_branches = [] self.options = opts end def color(string, clr) if options[:color] puts(string.send(clr)) else puts(string) end end def report_summary puts color(">>> Processed #{branch_count} branches in [#{elapsed}] seconds", :red) color(">>> Branches with NO commits in the last #{options[:exclude_days]} days: [#{matched_count}]", :red) color(">>> Branches with commits in the last #{options[:exclude_days]} days: [#{excluded_branches.count}]", :red) end def process self.matched_count = matched_branches.count color(">>> #{matched_count} remote branches with no commits in the last #{options[:exclude_days]} days:", :green) puts puts matched_branches.sort end def merged_branches @branches ||= begin current_origin = nil cmd = "git branch -r --merged #{options[:branch]}" merged_list = `#{cmd}`.split("\n").collect(&:strip) fail "Error running: #{cmd}. See output above ^^^" unless $?.exitstatus == 0 # find and delete the HEAD pointer and current branch origin head_pointer = merged_list.grep(/ -> /).first current_origin = head_pointer.split(/ -> /).last merged_list.delete_if { |elem| [head_pointer, current_origin].include?(elem) } end end def matched_branches today = Date.today @sorted ||= merged_branches.map do |branch| self.branch_count += 1 date_strings = `git show --format="%ci|%cr" #{branch} | head -n 1`.chomp.split('|') last_commit_date = Date.strptime(date_strings.first, '%Y-%m-%d') days_old = (today - last_commit_date).to_i if recent_branch?(days_old) excluded_branches << branch nil else BranchEntry.new(branch, last_commit_date, date_strings.last) end end.compact end # Determine if a branch has any commits within the last options[:exclude_days] days def recent_branch?(branch_age) branch_age.to_i <= options[:exclude_days].to_i end end GitMergedBranches.run