Last active
May 16, 2024 17:01
-
-
Save TALlama/70f2baf58111888a364c994a8b9075d7 to your computer and use it in GitHub Desktop.
Keep your local git branches clean! This is a script I use to loop through all my local branches, then delete any branches that have already landed in upstream. It will notice if it landed as a merge commit or a rebase. It will list out what's merged and not for any branches it keeps, so you can tell what you should revisit and what you should g…
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 "colorize" | |
class Branch | |
attr_reader :name, :base_branch | |
def initialize(name, base) | |
@name = name | |
@base_branch = base || %x{git log -1 --format="%h" @{u}}.chomp | |
end | |
def to_s | |
[ | |
can_pit? ? "[PIT] " : "", | |
name, | |
"\n", | |
"-"*80, | |
"\n", | |
commits, | |
"\n", | |
"-"*80, | |
].flatten.join | |
end | |
def commits_to_s | |
return '' if commits.empty? | |
"# ".blue + commits.join("\n# ".blue) | |
end | |
def commits | |
@commits ||= %x{git cherry -v #{base_branch} #{name}}.chomp.split("\n").reject(&:empty?).map {|l| l.start_with?("+") ? l.green : l } | |
end | |
def can_pit? | |
@can_pit ||= commits.all? {|c| c.start_with? '-'} | |
end | |
def self.all_names | |
%x{git branch}.split - ["*"] | |
end | |
def self.find(base: nil, names: (ARGV.length > 0 ? ARGV : Branch.all_names)) | |
names.map {|n| Branch.new(n, base)} | |
end | |
def self.current | |
@current ||= (%x{git branch}.split("\n").grep(/[*]/) || ['']).first[2..-1] | |
end | |
end | |
dry_run = ARGV[0] == '--dry-run' | |
ARGV.shift if dry_run | |
base_branch = (ARGV.shift; ARGV.shift) if ARGV[0] == '--branch' | |
all = Branch.find(base: base_branch) | |
puts "# PITTING #{"#"*70}".blue.bold | |
puts "# (dry run only; will not delete branches)".blue if dry_run | |
all.select(&:can_pit?).each do |b| | |
puts(*["git br -D #{b.name}", b.commits_to_s].reject(&:empty?)) | |
if b.name == Branch.current | |
puts "# (can't delete; it's the current branch)".blue | |
else | |
%x{git br -D #{b.name}} unless dry_run | |
end | |
puts | |
end | |
puts "# KEEPING #{"#"*70}".blue.bold | |
all.reject(&:can_pit?).each {|b| puts "# keeping ".blue + b.name.blue.bold + "; green commits have not merged", b.commits_to_s, ""} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sample output: