Last active
October 7, 2021 14:06
-
-
Save mrietveld/088e09d3ac90e380bd962062422b15b1 to your computer and use it in GitHub Desktop.
The rebranch.pl script for rebasing all (working) branches onto master.
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/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