chiark / gitweb /
git-debrebase: avoid rewrite better
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 9 Feb 2017 00:11:51 +0000 (00:11 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 16 Jun 2018 11:25:49 +0000 (12:25 +0100)
git-debrebase

index e231b51..6542c65 100755 (executable)
@@ -222,7 +222,7 @@ sub launder ($$$) {
     my ($input, $pseudos_must_overwrite_this, $wantdebonly) = @_;
     # go through commits backwards
     # we generate two lists of commits to apply
-    my (@deb_cl, @ups_cl);
+    my (@deb_cl, @ups_cl, @processed);
     my %found;
     my @pseudomerges;
 
@@ -234,6 +234,9 @@ sub launder ($$$) {
        $ms .= "\n\n[git-debrebase $appendinfo]\n";
        return (Msg => $ms);
     };
+    my $rewrite_from_here = sub {
+       push @processed, { SpecialMethod => 'StartRewrite' };
+    };
 
     my $cur = $input;
 
@@ -245,13 +248,16 @@ sub launder ($$$) {
        my $p0 = $cl->{Parents}[0]{CommitId};
        if ($ty eq 'AddPatches') {
            $cur = $p0;
+           $rewrite_from_here->();
            next;
        } elsif ($ty eq 'Packaging') {
            push @deb_cl, $cl;
+           push @processed, $cl;
            $cur = $p0;
            next;
        } elsif ($ty eq 'Upstream') {
            push @ups_cl, $cl;
+           push @processed, $cl;
            $cur = $p0;
            next;
        } elsif ($ty eq 'Mixed') {
@@ -262,12 +268,14 @@ sub launder ($$$) {
            };
            $queue->(\@deb_cl, "debian");
            $queue->(\@ups_cl, "upstream");
+           $rewrite_from_here->();
            next;
        } elsif ($ty eq 'Pseudomerge') {
            if (defined $pseudos_must_overwrite_this) {
                confess 'xxx actually check this';
            }
            push @pseudomerges, $cl;
+           $rewrite_from_here->();
            $cur = $ty->{Contributor};
            next;
        } elsif ($ty eq 'BreakwaterUpstreamMerge') {
@@ -299,6 +307,7 @@ sub launder ($$$) {
            };
            my $differs = get_differs $previous_breakwater, $cl->{Tree};
            $basis = launder $pseudomerges[0]{Overwritten}, undef, 1;
+           $rewrite_from_here->();
            last;
        } else {
            die "Reached difficult commit $cur: ".Dumper($cl);
@@ -309,6 +318,8 @@ sub launder ($$$) {
     workarea_fresh();
     in_workarea sub { xxx attributes xxx };
 
+    my $rewriting = 1;
+
     my $build = $basis;
 
     my $rm_tree_cached = sub {
@@ -328,8 +339,6 @@ sub launder ($$$) {
  
     my $committer_authline = calculate_committer_authline();
 
-    my $need_rewrite = 0;
-
     in_workarea sub {
        mkdir $rd or $!==EEXIST or die $!;
        my $current_method;
@@ -346,17 +355,19 @@ sub launder ($$$) {
                $read_tree_debian->($cltree);
            } elsif ($method eq 'Upstream') {
                $read_tree_upstream->($cltree);
+           } elsif ($method eq 'StartRewrite') {
+               $rewriting = 1;
+               next;
            } elsif ($method eq 'DgitImportDebianUpdate') {
                $read_tree_debian->($cltree);
                $rm_tree_cached(qw(debian/patches));
-               $need_rewrite = 1;
            } elsif ($method eq 'DgitImportUpstreamUpdate') {
                $read_tree_upstream->($cltree);
                push @parents, map { $_->{CommitId} } @{ $cl->{OrigParents} };
-               $need_rewrite = 1;
            } else {
                confess "$method ?";
            }
+           $rewriting ||= $cl ne pop @processed;
            my $newtree = cmdoutput @git, qw(write-tree);
            my $ch = $cl->{Hdr};
            $ch =~ s{^tree .*}{tree $newtree}m or confess "$ch ?";
@@ -364,24 +375,20 @@ sub launder ($$$) {
            $ch =~ s{(?=^author}{
                map { "parent $_\n" } @parents
            }me or confess "$ch ?";
-           foreach my $rewrite ($need_rewrite ? 1 : qw(0 1)) {
-               if ($rewrite) {
-                   $ch =~ s{^committer .*$}{$committer_authline}m
-                       or confess "$ch ?";
-                   $need_rewrite = 1;
-               }
-               my $cf = "$rd/m$rewrite"
-               open CD, ">", $cf or die $!;
-               print CD $ch, "\n", $cl->{Msg}; or die $!;
-               close CD or die $!;
-               my @cmd = (@git, qw(hash-object));
-               push @cmd, qw(-w) if $rewrite;
-               push @cmd, qw(-t commit), $cf;
-               my $newcommit = cmdoutput @cmd;
-               next unless $rewrite or $newcommit eq $cl->{CommitId};
-               $build = $newcommit;
-               last;
+           if ($rewrite) {
+               $ch =~ s{^committer .*$}{$committer_authline}m
+                   or confess "$ch ?";
            }
+           my $cf = "$rd/m$rewrite"
+               open CD, ">", $cf or die $!;
+           print CD $ch, "\n", $cl->{Msg}; or die $!;
+           close CD or die $!;
+           my @cmd = (@git, qw(hash-object));
+           push @cmd, qw(-w) if $rewrite;
+           push @cmd, qw(-t commit), $cf;
+           my $newcommit = cmdoutput @cmd;
+           confess "$ch ?" unless $rewrite or $newcommit eq $cl->{CommitId};
+           $build = $newcommit;
        }
     };