add a way to permanently reject an upstream commit
authorRudolf Polzer <divverent@alientrap.org>
Fri, 22 Apr 2011 06:15:05 +0000 (08:15 +0200)
committerRudolf Polzer <divverent@alientrap.org>
Fri, 22 Apr 2011 06:15:05 +0000 (08:15 +0200)
git-branch-manager

index 1ab7dda..8c84c12 100755 (executable)
@@ -9,6 +9,8 @@ my %color =
        '' => "\e[m",
        'outstanding' => "\e[1;33m",
        'unmerge' => "\e[1;31m",
+       'reject' => "\e[31m",
+       'unreject' => "\e[31m",
        'merge' => "\e[32m",
        'base' => "\e[1;34m",
        'previous' => "\e[34m",
@@ -18,7 +20,9 @@ my %html_style =
 (
        '' => "color: black; background-color: black",
        'outstanding' => "color: black; background-color: yellow",
-       'unmerge' => "color: black; background-color: red",
+       'unmerge' => "color: black; background-color: lightred",
+       'reject' => "color: black; background-color: red",
+       'unreject' => "color: black; background-color: red",
        'merge' => "color: black; background-color: green",
        'base' => "color: black; background-color: lightblue",
        'previous' => "color: black; background-color: blue",
@@ -28,6 +32,8 @@ my %name =
 (
        'outstanding' => "OUTSTANDING",
        'unmerge' => "UNMERGED",
+       'reject' => "REJECTED",
+       'unreject' => "UNREJECTED",
        'merge' => "MERGED",
        'base' => "BASE",
        'previous' => "PREVIOUS",
@@ -100,6 +106,98 @@ sub reset_to_commit($)
        }
 }
 
+sub reject_commit($)
+{
+       # reject == merge but skip
+       my ($r) = @_;
+       my $cmsg = "";
+       my $author = "";
+       my $email = "";
+       my $date = "";
+       if($do_commit)
+       {
+               $logcache = undef;
+               my $msg = backtick 'git', 'log', '-1', '--pretty=fuller', $r
+                       or die "git-log: $!";
+               for(split /\n/, $msg)
+               {
+                       if(/^Author:\s*(.*) <(.*)>/)
+                       {
+                               $author = $1;
+                               $email = $2;
+                       }
+                       elsif(/^AuthorDate:\s*(.*)/)
+                       {
+                               $date = $1;
+                       }
+                       elsif(/^    (.*)/)
+                       {
+                               $cmsg .= "$1\n";
+                       }
+               }
+               open my $fh, '>', '.commitmsg'
+                       or die ">.commitmsg: $!";
+               print $fh "$cmsg" . "::stable-branch::reject=$r\n"
+                       or die ">.commitmsg: $!";
+               close $fh
+                       or die ">.commitmsg: $!";
+       }
+       local $ENV{GIT_AUTHOR_NAME} = $author;
+       local $ENV{GIT_AUTHOR_EMAIL} = $email;
+       local $ENV{GIT_AUTHOR_DATE} = $date;
+       if($do_commit)
+       {
+               run 'git', 'commit', '--allow-empty', '-F', '.commitmsg'
+                       or die "git-commit: $!";
+       }
+}
+
+sub unreject_commit($)
+{
+       # reject == merge but skip
+       my ($r) = @_;
+       my $cmsg = "";
+       my $author = "";
+       my $email = "";
+       my $date = "";
+       if($do_commit)
+       {
+               $logcache = undef;
+               my $msg = backtick 'git', 'log', '-1', '--pretty=fuller', $r
+                       or die "git-log: $!";
+               for(split /\n/, $msg)
+               {
+                       if(/^Author:\s*(.*) <(.*)>/)
+                       {
+                               $author = $1;
+                               $email = $2;
+                       }
+                       elsif(/^AuthorDate:\s*(.*)/)
+                       {
+                               $date = $1;
+                       }
+                       elsif(/^    (.*)/)
+                       {
+                               $cmsg .= "$1\n";
+                       }
+               }
+               open my $fh, '>', '.commitmsg'
+                       or die ">.commitmsg: $!";
+               print $fh "$cmsg" . "::stable-branch::unreject=$r\n"
+                       or die ">.commitmsg: $!";
+               close $fh
+                       or die ">.commitmsg: $!";
+       }
+       local $ENV{GIT_AUTHOR_NAME} = $author;
+       local $ENV{GIT_AUTHOR_EMAIL} = $email;
+       local $ENV{GIT_AUTHOR_DATE} = $date;
+       if($do_commit)
+       {
+               run 'git', 'commit', '--allow-empty', '-F', '.commitmsg'
+                       or die "git-commit: $!";
+       }
+}
+
 sub merge_commit($)
 {
        my ($r) = @_;
@@ -218,7 +316,11 @@ sub rebase_log($$)
 
        for(0..$newbase_id)
        {
-               if(!$log->{bitmap}[$_])
+               if($log->{bitmap}[$_] < 0)
+               {
+                       unshift @rlog, ['reject', $log->{order_a}[$_]];
+               }
+               elsif(!$log->{bitmap}[$_])
                {
                        unshift @rlog, ['unmerge', $log->{order_a}[$_]];
                }
@@ -226,10 +328,14 @@ sub rebase_log($$)
 
        for($newbase_id+1 .. @{$log->{order_a}}-1)
        {
-               if($log->{bitmap}[$_])
+               if($log->{bitmap}[$_] > 0)
                {
                        push @rlog, ['merge', $log->{order_a}[$_]];
                }
+               elsif($log->{bitmap}[$_] < 0)
+               {
+                       push @rlog, ['reject', $log->{order_a}[$_]];
+               }
                else
                {
                        push @outstanding, ['outstanding', $log->{order_a}[$_]];
@@ -316,6 +422,14 @@ sub parse_log()
                {
                        push @logdata, ['merge', $1];
                }
+               elsif($data =~ /::stable-branch::reject=(\S+)/)
+               {
+                       push @logdata, ['reject', $1];
+               }
+               elsif($data =~ /::stable-branch::unreject=(\S+)/)
+               {
+                       push @logdata, ['unreject', $1];
+               }
                elsif($data =~ /::stable-branch::reset=(\S+)/)
                {
                        @logdata = ();
@@ -359,6 +473,14 @@ sub parse_log()
                        {
                                $bitmap[$history{$data}] = 0;
                        }
+                       elsif($cmd eq 'reject')
+                       {
+                               $bitmap[$history{$data}] = -1;
+                       }
+                       elsif($cmd eq 'unreject')
+                       {
+                               $bitmap[$history{$data}] = 0;
+                       }
                        elsif($cmd eq 'rebase')
                        {
                                # the bitmap is fine, but generate a new log from the bitmap
@@ -450,7 +572,7 @@ sub run_script(@)
                        {
                                my $l = parse_log();
                                die "PEBKAC: invalid revision number, cannot reset"
-                                       unless defined $l->{order_h}{$r} and not $l->{bitmap}[$l->{order_h}{$r}];
+                                       unless defined $l->{order_h}{$r} and $l->{bitmap}[$l->{order_h}{$r}] == 0;
                                die "PEBKAC: not initialized"
                                        unless defined $l->{base};
                        }
@@ -462,12 +584,36 @@ sub run_script(@)
                        {
                                my $l = parse_log();
                                die "PEBKAC: invalid revision number, cannot reset"
-                                       unless defined $l->{order_h}{$r} and $l->{bitmap}[$l->{order_h}{$r}];
+                                       unless defined $l->{order_h}{$r} and $l->{bitmap}[$l->{order_h}{$r}] > 0;
                                die "PEBKAC: not initialized"
                                        unless defined $l->{base};
                        }
                        unmerge_commit $r;
                }
+               elsif($cmd eq 'reject')
+               {
+                       if($pebkac)
+                       {
+                               my $l = parse_log();
+                               die "PEBKAC: invalid revision number, cannot reset"
+                                       unless defined $l->{order_h}{$r} and $l->{bitmap}[$l->{order_h}{$r}] == 0;
+                               die "PEBKAC: not initialized"
+                                       unless defined $l->{base};
+                       }
+                       reject_commit $r;
+               }
+               elsif($cmd eq 'unreject')
+               {
+                       if($pebkac)
+                       {
+                               my $l = parse_log();
+                               die "PEBKAC: invalid revision number, cannot reset"
+                                       unless defined $l->{order_h}{$r} and $l->{bitmap}[$l->{order_h}{$r}] < 0;
+                               die "PEBKAC: not initialized"
+                                       unless defined $l->{base};
+                       }
+                       unreject_commit $r;
+               }
                elsif($cmd eq 'outstanding')
                {
                }