The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

#!perl
use strict;
package Options;
our $VERSION = '1.000001';
use Moo;
option all => (
is => 'ro',
required => 0,
doc => 'regex to filter branches',
);
option grep => (
is => 'ro',
format => 's',
required => 0,
doc => 'regex to filter branches',
);
package main;
our $VERSION = '0.000022';
use Capture::Tiny qw( capture );
use String::Trim qw( trim );
use Term::Choose 1.743 ();
## no critic (ControlStructures::ProhibitMutatingListFunctions)
my $options = Options->new_with_options;
# Don't include the branch we're currently on
my @branches = map { trim($_) }
grep { !m{^\*} }
git::branch( '--no-color', $options->all ? ('--all') : () );
if ( $options->grep ) {
@branches = grep { $_ =~ $options->grep } @branches;
}
## use critic
my $term = Term::Choose->new;
my @reply = $term->choose(
\@branches,
{ layout => 2, prompt => 'Which branch(es) would you like to delete?', }
);
for my $branch (@reply) {
my @to_delete = ($branch);
for my $name (@to_delete) {
my $is_remote = $name =~ s{\Aremotes/}{};
if ( my $stderr
= delete_branch( $is_remote ? ('--remotes') : (), $name ) ) {
if ( $stderr =~ m{not fully merged} ) {
my $prompt = <<"EOF";
Branch $branch is not fully merged. Would you still like to delete it?",
EOF
my $reply
= $term->choose( [ 'Yes', 'No' ], { prompt => $prompt } );
if ( $reply eq 'Yes' ) {
my $stderr = delete_branch( '--force', $name );
print "$stderr\n" if $stderr;
}
}
else {
print "$stderr\n";
}
}
}
}
sub delete_branch {
my @args = @_;
unshift @args, '--delete';
my ( undef, $stderr ) = capture {
eval { git::branch(@args) };
};
return $stderr;
}
sub remotes {
my $branch = shift;
my @remotes = map { trim($_) } git::branch( '-r', '--contains', $branch );
return @remotes;
}
# ABSTRACT: Interactively delete git branches
# PODNAME: delete-git-branches
__END__
=pod
=encoding UTF-8
=head1 NAME
delete-git-branches - Interactively delete git branches
=head1 VERSION
version 1.000001
=head1 SYNOPSIS
$ git branch
* delete-branches
foo
foo-bar
foo-bar-baz
foo-bar-baz-qux
master
$ delete-git-branches
1> foo
2> foo-bar
3> foo-bar-baz
4> foo-bar-baz-qux
5> master
Which branch(es) would you like to delete? : 1 2 3 4
$ git branch
* delete-branches
master
=head2 DESCRIPTION
Interactive command line script which allows you to select one or many git
branches to delete. Use C<ctrl-c> to exit without deleting any branches.
=head2 OPTIONS
=over
=item all
Includes remote branches when enabled.
$ delete-git-branches --all
1> foo-bar-baz
2> foo-bar-baz-qux
3> master
4> remotes/origin/cpan-repo
5> remotes/origin/delete-branches
6> remotes/origin/foo
=item grep
A regex to filter git branches against.
$ delete-git-branches --grep foo
1> foo-bar-baz
2> foo-bar-baz-qux
=back
=head1 AUTHOR
Olaf Alders <olaf@wundercounter.com>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2015 by Olaf Alders.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut