Skip to content

Instantly share code, notes, and snippets.

@mrietveld
Last active October 7, 2021 14:06
Show Gist options
  • Save mrietveld/088e09d3ac90e380bd962062422b15b1 to your computer and use it in GitHub Desktop.
Save mrietveld/088e09d3ac90e380bd962062422b15b1 to your computer and use it in GitHub Desktop.
The rebranch.pl script for rebasing all (working) branches onto master.
#!/usr/bin/perl
use Cwd;
use Time::Local;
use Getopt::Std;
use POSIX 'strftime';
our($opt_h, $opt_p, $opt_r, $opt_s, $opt_u, $opt_v, $opt_O, $opt_P, $opt_U, $opt_S, $opt_a );
getopts('hpr:s:uvO:U:P:a');
# TODO: add general description
if( $opt_h ) {
print( "\n "
. "-h : [h]elp (brief)\n "
. "-p : [p]ush de branch naar origin\n "
. "-r <branch> : te[r]ug naar deze branch na het rebranchen\n "
. "-s <secs> : [s]laap voor het gegeven aantal seconden tussen het rebranchen\n "
. "-u : [u]pdate master/main op basis van de upstream repository\n "
. "-v : [v]anaf: start at the current branch (default: is the most recent (authordate) branch)\n "
. "-O <origin> : gebruik de gegeven [O]rigin repo wanneer je branch [p]usht \n "
. "-P <prefix> : gebruik het gegeven [P]refix voor het uitkiezen van branches [default \"_\"]\n "
. "-S <suffix> : gebruik het gegeven [S]ufffix voor het uitkiezen van branches [default \"_\"]\n "
. "-U <repo-name> : gebruik de gegeven [U]pstream repo voor het halen van niewe data/updaten \n "
. "-a : rebranch **[A]LLE** branches\n "
. "\n");
exit;
}
my $vanaf = 0;
if( $opt_v ) {
$vanaf = 1;
}
my $git="/usr/bin/git";
my $sleep = 0;
if( $opt_s ) {
$sleep = $opt_s;
}
my $upstream="upstream";
if( $opt_U ) {
$upstream=$opt_U;
}
my $origin="origin";
if( $opt_O ) {
$origin=$opt_O;
}
my $prefix="_";
if( $opt_P ) {
$prefix=$opt_P;
}
my $suffix="_";
if( $opt_P ) {
$suffix=$opt_S;
}
if( ($opt_P || $opt_S) && $opt_a ) {
die "\nYou can only specify \n 1) a specific prefix (-P <prefix>) or a specific suffix ( -S <suffix> ) OR \n 2) that you want to rebranch *ALL* branches (-a) \nNOT BOTH!\n\n"
}
if( $opt_a ) {
$prefix=""
}
if( $opt_p ) {
if( $upstream eq $origin ) {
die "Pushing branches to $origin doesn't seem like a good idea.. Try again?\n\n";
}
}
# get current branch
my $cmd = "$git status -bs";
open( STATUS , "$cmd |" )
|| die "Unable to execute \"$cmd\": $!\n";
my $curbr,$retbr;
while(<STATUS>) {
if( /#\s+(\S+?)(\.\.\.\S+)?\s.*$/ ) {
$curbr = $1;
} else {
die "?? $_";
}
}
$main_branch = "master";
$branch_check_output=`git branch --list $main_branch`;
if( length($branch_check_output) == 0) {
$main_branch = "main";
}
if( $curbr eq $main_branch ) {
$vanaf = 0;
}
$retbr = $curbr;
if( $opt_r ) {
$retbr=$opt_r;
}
$cmd = "$git checkout $main_branch";
system($cmd);
if( $? != 0 ) {
die "Unable to checkout $main_branch are there un-checked-in changes? [$!]\n\n";
}
if( $opt_u ) {
my $cmd = "$git remote update -p";
system($cmd);
if( $? != 0 ) {
die "Unable to update from remote repositories: please check the status of the repository! [$!]\n\n";
}
my $cmd = "$git merge --ff ${upstream}/$main_branch";
system($cmd);
if( $? != 0 ) {
die "Unable to merge fast-forward to ${upstream}/$main_branch please check the status of the repository! [$1]\n\n";
}
if( $sleep > 0 ) {
sleep $sleep;
}
}
open(BRANCH, "$git branch --sort=-authordate |" )
|| die "Unable to execute '$git branch': $!\n\n";
my @branches;
my $br, $ver;
while(<BRANCH>) {
chomp;
if( /^\*?\s+(${prefix}[^\s]+?([^-]+))$/ || /^\*?\s+([^\s]+?${suffix})$/ ){
$br = $1;
$ver = $3;
if( $ver =~ /^\d\.\d(\.x)?$/ ) {
print "> Skipping branch '$br'\n";
next;
}
if( $vanaf ) {
if( $br eq $curbr ) {
$vanaf = 0;
} else {
next;
}
}
push @branches, $br;
}
}
foreach my $br (@branches) {
my $cmd = "$git checkout -q $br";
system($cmd);
if( $? != 0 ) {
die "Unable to change to [$br]: there are likely un-checked-in existing changes.\n\n";
}
print "\nRebasing $br onto $main_branch\n===\n";
$cmd = "$git rebase $main_branch";
system($cmd);
if( $? != 0 ) {
die "Unable to rebase [$br] onto $main_branch please fix and continue the rebase!\n\n";
}
$cmd = "$git status -s";
system($cmd);
if( $? != 0 ) {
die "Unable to check the status on [$br]: something is HUGELY WRONG!\n\n";
}
if( $opt_p ) {
$cmd = "$git push -f $origin $br";
system($cmd);
if( $? != 0 ) {
die "Unable to push $br to repository $origin!\n\n";
}
}
if( $sleep > 0 ) {
# git push?
my $now = time;
my $afterSleep = $now + $sleep;
my $afterSleepStr = strftime('%H:%M:%S', localtime(time + $sleep));
print "Continuing in $sleep seconds at $afterSleepStr...\n\n";
sleep $sleep;
}
}
print "\n";
$cmd = "$git checkout $retbr";
system($cmd);
if( $? != 0 ) {
die "Unable to checkout $retbr [$!]\n\n";
}
print "\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment