From 31c92af6af884c6ed5b283376052be9415331fcb Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Wed, 12 Feb 2025 11:05:23 +0100 Subject: [PATCH] Bug 39106: The auto-rebase script - Add --bugzilla Julian wrote a script a while ago to retrieve patches from bugzilla and checkout the good commit to make sure the patches will apply cleanly. This change reuses the same logic for the auto-rebase script. Test plan: 0. a. You will need to install REST::Client using cpanm: `cpanm REST::Client` b. You need the --confirm flag from git-bz, see https://gitlab.com/koha-community/git-bz/-/issues/14 1. Pick a bug number with patches that does not apply on current main 2. Use the auto_rebase script with the --bugzilla option 3. Enjoy --- misc/devel/auto_rebase.pl | 118 +++++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 34 deletions(-) diff --git a/misc/devel/auto_rebase.pl b/misc/devel/auto_rebase.pl index ede46b931d4..fd1bd7d8f53 100755 --- a/misc/devel/auto_rebase.pl +++ b/misc/devel/auto_rebase.pl @@ -8,17 +8,20 @@ use List::Util qw( first ); use Getopt::Long; use Pod::Usage; use Try::Tiny; +use REST::Client; +use JSON qw( decode_json ); $Term::ANSIColor::AUTOLOCAL = 1; my $git_dir = '.'; my $target_branch = 'main'; -my ( $new_branch, $nb_commits, $help ); +my ( $new_branch, $nb_commits, $bug_number, $help ); GetOptions( 'git-dir=s' => \$git_dir, 'target-branch=s' => \$target_branch, 'new-branch=s' => \$new_branch, 'n=s' => \$nb_commits, + 'bugzilla=s' => \$bug_number, 'help|?' => \$help, ) or pod2usage(2); @@ -54,7 +57,13 @@ try { exit 2; }; -my ($source_branch) = $git->RUN( 'symbolic-ref', '--short', 'HEAD' ); +my $source_branch; +if ($bug_number) { + $source_branch = "bug_$bug_number"; + switch_branch($source_branch); +} else { + ($source_branch) = $git->RUN( 'symbolic-ref', '--short', 'HEAD' ); +} # Bug 38664 is "Tidy the whole codebase" my @tidy_commits = grep { m{\|Bug 38664: } } $git->RUN( 'log', '--format=%h|%s', $target_branch ); @@ -66,27 +75,63 @@ my ($tidy_commit) = split '\|', $tidy_commits[0]; my ($commit_before_tidy) = split '\|', $tidy_commits[-1]; $commit_before_tidy .= '^1'; -# Do not do anything if we have the tidy commits in the git log -if ( $git->branch( $source_branch, '--contains', $tidy_commit ) ) { - say GREEN "No need to rebase, your branch already contains the tidy commits!"; - exit; -} - my $tmp_src_branch = "$source_branch-tmp"; $new_branch ||= "$source_branch-rebased"; say BLUE "Creating a temporary branch '$tmp_src_branch'..."; -try { - $git->checkout( '-b', $tmp_src_branch ); -} catch { - say MAGENTA $_->error; - say RED sprintf "Cannot create and checkout branch '%s'.", $tmp_src_branch; - if ( $_->error =~ m{already exists} ) { - say RED "Delete it and try again."; - say sprintf "\t\$ git branch -D %s", $tmp_src_branch; +switch_branch($tmp_src_branch); + +if ($bug_number) { + say BLUE sprintf "Guessing a date to use from bugzilla's bug %s", $bug_number; + my $client = REST::Client->new( + { + host => 'https://bugs.koha-community.org/bugzilla3/rest', + } + ); + + $client->GET("/bug/$bug_number/attachment?include_fields=is_patch,is_obsolete,creation_time,summary"); + my $response = decode_json( $client->responseContent ); + + my $time; + foreach my $attachment ( @{ $response->{bugs}->{$bug_number} } ) { + next if ( $attachment->{is_obsolete} ); + next if ( !$attachment->{is_patch} ); + + $time = $attachment->{creation_time}; + last; } - exit 2; -}; + + unless ($time) { + say RED sprintf "No non-obsolete patch found on bug %s", $bug_number; + exit 2; + } + say GREEN sprintf "First patch from this bug was applied at %s", $time; + + my ($commit) = $git->rev_list( '-n', 1, '--before', $time, $target_branch ); + unless ($commit) { + say RED sprintf "No commit found before %s on '%s'", $time, $target_branch; + exit 2; + } + + say BLUE "Resetting HEAD to where origin/main was at $time (commit $commit)"; + $git->reset( '--hard', $commit ); + try { + say BLUE "Applying patches using git bz"; + $git->bz( 'apply', $bug_number, '--confirm' ); + } catch { + say MAGENTA $_->error; + say RED "Cannot apply the patches cleanly"; + say BLUE + "You can continue git-bz operation without this script. Once all the patches are applied retry without --bugzilla."; + exit 2; + } +} + +# Do not do anything if we have the tidy commits in the git log +if ( $git->branch( $tmp_src_branch, '--contains', $tidy_commit ) ) { + say GREEN "No need to rebase, your branch already contains the tidy commits!"; + exit; +} # Rebase the branch up to before the tidy work unless ( $git->branch( $source_branch, '--contains', $commit_before_tidy ) ) { @@ -109,17 +154,7 @@ unless ( $git->branch( $source_branch, '--contains', $commit_before_tidy ) ) { # Create a new branch say BLUE "Creating a new branch '$new_branch' starting at the end of the tidy commits..."; -try { - $git->checkout( '-b', $new_branch, $tidy_commit ); -} catch { - say MAGENTA $_->error; - say RED sprintf "Cannot create and checkout branch '%s'.", $new_branch; - if ( $_->error =~ m{already exists} ) { - say RED "Delete it and try again."; - say sprintf "\t\$ git branch -D %s", $new_branch; - } - exit 2; -}; +switch_branch( $new_branch, $tidy_commit ); # Get the list of commits from the source branch say BLUE "Getting commit list from branch '$tmp_src_branch'..."; @@ -215,6 +250,21 @@ sub get_commit_info { return ( $author, $date, $message ); } +sub switch_branch { + my ( $branch, $commit ) = @_; + try { + $git->checkout( '-b', $branch, $commit || () ); + } catch { + say MAGENTA $_->error; + say RED sprintf "Cannot create and checkout branch '%s'.", $branch; + if ( $_->error =~ m{already exists} ) { + say RED "Delete it and try again."; + say sprintf "\t\$ git branch -D %s", $branch; + } + exit 2; + }; +} + =head1 NAME auto_rebase.pl - Automate rebasing and resolving conflicts during Git rebases. @@ -228,6 +278,7 @@ auto_rebase.pl [options] --target-branch Target branch to rebase onto (default: main) --new-branch The resulting branch (default: ${source-branch}-rebased) -n The number of commits to pick for rebase from the source branch + --bugzilla Pull patches from bugzilla --help Show this help message =head1 DESCRIPTION @@ -240,11 +291,6 @@ The source branch is the branch that is currently checked out. =head1 EXAMPLES -First you need to retrieve this script from the main branch, do not place it under misc/devel/auto_rebase.pl or you will get an error (`The following untracked working tree files would be overwritten by checkout`). - - git show origin/main:misc/devel/auto_rebase.pl > auto_rebase.pl - chmod +x auto_rebase.pl - Rebase onto 'main' in the current repository: ./auto_rebase.pl @@ -261,6 +307,10 @@ Rebase onto 'main' the last 42 commits of the current branch ./auto_rebase.pl -n 42 +Rebase onto 'main' the patches from bugzilla's bug 42424 + + ./auto_rebase.pl --bugzilla 42424 + =head1 AUTHOR Jonathan Druart -- 2.34.1