Skip to content

Instantly share code, notes, and snippets.

@adamtaylor
Last active October 4, 2019 23:36
Show Gist options
  • Save adamtaylor/720be12a3429d1df17b1611b92ba8f56 to your computer and use it in GitHub Desktop.
Save adamtaylor/720be12a3429d1df17b1611b92ba8f56 to your computer and use it in GitHub Desktop.
Script to archive branches older than two years
#!perl
use strict;
use warnings;
use feature 'say';
use DateTime;
use DateTime::Format::ISO8601;
# Very crude argument handling/safety check
say "Usage: $0 for_real # really perform actions";
my $for_real = $ARGV[0];
# List all branches with date and commit hash
# https://git-scm.com/docs/git-for-each-ref
my @branches = `git for-each-ref --sort='-committerdate:iso8601' --format=' %(committerdate:iso8601)%09%(refname)%09%(objectname)' refs/remotes`;
say "Checking " . @branches . " branches for archival";
my $now = DateTime->now;
my $two_years_ago = $now->clone->subtract( years => 2 );
my @to_archive;
my $count = 0;
foreach my $branch ( @branches ) {
chomp $branch;
$branch =~ s/^\s+//g;
# $branch e.g. 2013-08-20 20:39:02 +0300 refs/remotes/origin/branch-name
my ( $datetime, $branch_name, $commit ) = split( /\t/, $branch );
# Skip the dev branch, the master branch and the current (*) branch
next if $branch_name eq 'dev' or $branch_name eq 'master' or $branch_name =~ /\*/;
( my $trimmed_branch = $branch_name ) =~ s/refs\/remotes\/origin\///;
# DateTime::Format::ISO8601 doesn't seem to like the +xxxx on the datetime
my ( $ymd, $time, undef ) = split('\s', $datetime);
my $branch_dt = DateTime::Format::ISO8601->parse_datetime( $ymd . 'T' . $time );
# Archive any branches older than two years
if ( $branch_dt < $two_years_ago ) {
push @to_archive, $trimmed_branch;
if ( $for_real ) {
say "git tag archive/$trimmed_branch $commit";
`git tag archive/$trimmed_branch $commit`;
say "git branch -d $trimmed_branch";
`git branch -d $trimmed_branch`;
say "git push --delete origin $trimmed_branch";
`git push --delete origin $trimmed_branch`;
say "git push origin --tags";
`git push origin --tags`;
}
else {
say "Would have run:";
say "git tag archive/$trimmed_branch $commit";
say "git branch -d $trimmed_branch";
say "git push --delete origin $trimmed_branch";
say "git push origin --tags";
}
$count++;
}
}
if ( $for_real) {
say "Deleted $count branches";
}
else {
say "Would delete $count branches";
}
exit(0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment