Skip to content

Instantly share code, notes, and snippets.

@robertknight
Created January 2, 2013 18:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robertknight/4436783 to your computer and use it in GitHub Desktop.
Save robertknight/4436783 to your computer and use it in GitHub Desktop.
Script to print out the merge status of local branches with respect to an 'upstream' branch (by default, 'master'). For each local branch, it prints out the number and one-line summaries of commits that have not been merged. Run with the -m argument to print out just the merge status of each branch. The script looks at the diff introduced by com…
#!/usr/bin/env ruby
require 'optparse.rb'
upstream_branch = "master"
branch_names = []
show_merge_status = false
OptionParser.new do |parser|
parser.banner = <<END
#{$0} [options]
List commits in each branch that are not merged into an upstream
branch (by default, 'master').
END
parser.on('-u', '--upstream [name]', "Branch to compare against. Defaults to 'master'") do |branch|
upstream_branch = branch
end
parser.on('-b','--branches [names]', 'Comma-separated list of branches to compare against the upstream branch. Defaults to all local branches') do |branches|
branch_names = branches.split(',')
end
parser.on('-m','--merged', 'Print only the merge status of each branch with respect to the upstream branch') do
show_merge_status = true
end
end.parse!
def find_unmerged_commits(upstream_branch, head_branch)
commits = `git cherry #{upstream_branch} #{head_branch}`.each_line.select do |cherry_line|
cherry_line.start_with? '+'
end
commits.map! do |commit|
commit.strip.match(/[0-9a-f]+/)[0]
end
return commits
end
def print_unmerged_commits(commits, upstream_branch, head_branch)
if commits.empty?
return
end
puts "Commits in #{head_branch} not merged into #{upstream_branch} (#{commits.length}):"
commits.each do |id|
commit_info = `git log -n 1 --oneline #{id}`.strip
puts " #{commit_info}"
end
puts ""
end
if branch_names.empty?
`git branch`.each_line do |branch|
branch_names << branch.gsub(/^[ \*]+/,'').strip
end
end
branch_names.each do |branch_name|
unmerged_commits = find_unmerged_commits(upstream_branch, branch_name)
if show_merge_status
if unmerged_commits.empty?
puts "#{branch_name} is merged"
else
puts "#{branch_name} is not merged (#{unmerged_commits.length} commits not in #{upstream_branch})"
end
else
print_unmerged_commits unmerged_commits, upstream_branch, branch_name
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment