chiark / gitweb /
git-debrebase: NOTES: done test suite, pretty much
[dgit.git] / git-debrebase
index 1a62852e19ac765a0ed1e2175d37104e59f048ac..2b6584630516bb3208c0874413c1bbe791168f94 100755 (executable)
@@ -33,7 +33,8 @@
 #    git-debrebase [<options>] stitch [--prose=<for commit message>]
 #    git-debrebase [<options>] downstream-rebase-launder-v0  # experimental
 #
-#    git-debrebase [<options>] convert-from-gbp <upstream-git-rev>
+#    git-debrebase [<options>] convert-from-gbp [<upstream-git-rev>]
+#    git-debrebase [<options>] convert-to-gbp
 
 # problems / outstanding questions:
 #
@@ -110,7 +111,8 @@ sub cfg ($;$) {
        fail "missing required git config $k" unless $optional;
        return ();
     }
-    return split /\0/, $out;
+    my @l = split /\0/, $out;
+    return wantarray ? @l : $l[0];
 }
 
 memoize('cfg');
@@ -449,15 +451,24 @@ sub classify ($) {
                           Contributor => $identical[0]);
     }
     if (@p == 2 && @identical == 2) {
-       my @bytime = nsort_by {
-           my ($ph,$pm) = get_commit $_->{CommitId};
+       my $get_t = sub {
+           my ($ph,$pm) = get_commit $_[0]{CommitId};
            $ph =~ m/^committer .* (\d+) [-+]\d+$/m or die "$_->{CommitId} ?";
            $1;
-       } @p;
+       };
+       my @bytime = @p;
+       my $order = $get_t->($bytime[0]) <=> $get_t->($bytime[1]);
+       if ($order > 0) { # newer first
+       } elsif ($order < 0) {
+           @bytime = reverse @bytime;
+       } else {
+           # same age, default to order made by -s ours
+           # that is, commit was made by someone who preferred L
+       }
        return $classify->(qw(Pseudomerge),
                           SubType => qw(Ambiguous),
-                          Overwritten => [ $bytime[0] ],
-                          Contributor => $bytime[1]);
+                          Contributor => $bytime[0],
+                          Overwritten => [ $bytime[1] ]);
     }
     foreach my $p (@p) {
        my ($p_h, $p_m) = get_commit $p->{CommitId};
@@ -589,13 +600,16 @@ sub walk ($;$$) {
 
     my $bomb = sub { # usage: return $bomb->();
        print $report " Unprocessable" if $report;
+       print $report " ($cl->{Why})" if $report && defined $cl->{Why};
        $prprdelim->();
        if ($nogenerate) {
            return (undef,undef);
        }
        die "commit $cur: Cannot cope with this commit (d.".
            (join ' ', map { sprintf "%#x", $_->{Differs} }
-            @{ $cl->{Parents} }). ")";
+            @{ $cl->{Parents} }).
+           (defined $cl->{Why} ? "; $cl->{Why}": '').
+                ")";
     };
 
     my $build;
@@ -901,6 +915,7 @@ sub ffq_prev_branchinfo () {
     return ('weird-symref', 'HEAD symref is not to refs/')
        unless $current =~ m{^refs/};
     my $ffq_prev = "refs/$ffq_refprefix/$'";
+    printdebug "ffq_prev_branchinfo branch current $current\n";
     return ('branch', undef, $current, $ffq_prev);
 }
 
@@ -930,12 +945,15 @@ sub record_ffq_prev () {
     my @check_specs = split /\;/, (cfg "branch.$branch.ffq-ffrefs",1) // '*';
     my %checked;
 
+    printdebug "ffq check_specs @check_specs\n";
+
     my $check = sub {
        my ($lrref, $desc) = @_;
+       printdebug "ffq might check $lrref ($desc)\n";
        my $invert;
        for my $chk (@check_specs) {
            my $glob = $chk;
-           $invert = $glob =~ s{^[^!]}{};
+           $invert = $glob =~ s{^[!^]}{};
            last if fnmatch $glob, $lrref;
        }
        return if $invert;
@@ -945,7 +963,7 @@ sub record_ffq_prev () {
        if (is_fast_fwd $lrval, $currentval) {
            print "OK, you are ahead of $lrref\n" or die $!;
            $checked{$lrref} = 1;
-       } if (is_fast_fwd $currentval, $lrval) {
+       } elsif (is_fast_fwd $currentval, $lrval) {
            $checked{$lrref} = -1;
            fproblem 'behind', "you are behind $lrref, divergence risk";
        } else {
@@ -955,23 +973,25 @@ sub record_ffq_prev () {
     };
 
     my $merge = cfg "branch.$branch.merge",1;
-    if (defined $merge && $merge =~ m{^refs/heads/}) {
+    if (defined $merge and $merge =~ m{^refs/heads/}) {
        my $rhs = $';
+       printdebug "ffq merge $rhs\n";
        my $check_remote = sub {
-           my ($remote, $desc) = (@_);
+           my ($remote, $desc) = @_;
+           printdebug "ffq check_remote ".($remote//'undef')." $desc\n";
            return unless defined $remote;
            $check->("refs/remotes/$remote/$rhs", $desc);
        };
-       $check_remote->((cfg "branch.$branch.remote",1),
+       $check_remote->((scalar cfg "branch.$branch.remote",1),
                        'remote fetch/merge branch');
-       $check_remote->((cfg "branch.$branch.pushRemote",1) //
-                       (cfg "branch.$branch.pushDefault",1),
+       $check_remote->((scalar cfg "branch.$branch.pushRemote",1) //
+                       (scalar cfg "branch.$branch.pushDefault",1),
                        'remote push branch');
     }
     if ($branch =~ m{^dgit/}) {
-       $check->("remotes/dgit/$branch", 'remote dgit branch');
+       $check->("refs/remotes/dgit/$branch", 'remote dgit branch');
     } elsif ($branch =~ m{^master$}) {
-       $check->("remotes/dgit/dgit/sid", 'remote dgit branch for sid');
+       $check->("refs/remotes/dgit/dgit/sid", 'remote dgit branch for sid');
     }
 
     fproblems_maybe_bail();
@@ -1277,6 +1297,36 @@ sub cmd_convert_from_gbp () {
     update_head_checkout $old_head, $work, 'convert-from-gbp';
 }
 
+sub cmd_convert_to_gbp () {
+    badusage "no arguments allowed" if @ARGV;
+    my $head = get_head();
+    my $ffq = (ffq_prev_branchinfo())[3];
+    my $bw = breakwater_of $head;
+    fresh_workarea();
+    my $out;
+    in_workarea sub {
+       runcmd @git, qw(checkout -q -b bw), $bw;
+       runcmd @git, qw(checkout -q -b patch-queue/bw), $head;
+       runcmd qw(gbp pq export);
+       runcmd @git, qw(add debian/patches);
+       $out = make_commit ['HEAD'], [
+            'Commit patch queue (converted from git-debrebase format)',
+            '[git-debrebase convert-to-gbp: commit patches]',
+        ];
+    };
+    if (defined $ffq) {
+       runcmd @git, qw(update-ref -m),
+           "debrebase: converting corresponding main branch to gbp format",
+           $ffq, $git_null_obj;
+    }
+    update_head_checkout $head, $out, "convert to gbp (v0)";
+    print <<END or die $!;
+git-debrebase: converted to git-buildpackage branch format
+git-debrebase: WARNING: do not now run "git-debrebase" any more
+git-debrebase: WARNING: doing so would drop all upstream patches!
+END
+}
+
 sub cmd_downstream_rebase_launder_v0 () {
     badusage "needs 1 argument, the baseline" unless @ARGV==1;
     my ($base) = @ARGV;