chiark / gitweb /
changelog: start 6.1
[dgit.git] / git-debrebase
index c28a775..f002225 100755 (executable)
@@ -41,6 +41,8 @@ our ($opt_defaultcmd_interactive);
 
 our $us = qw(git-debrebase);
 
+$|=1;
+
 sub badusage ($) {
     my ($m) = @_;
     print STDERR "bad usage: $m\n";
@@ -270,12 +272,17 @@ sub snags_maybe_bail () {
                $us, $snags_tripped;
        } else {
            fail sprintf
-  "%s: snags: %d blockers (you could -f<tag>, or --force)",
+  "%s: snags: %d blocker(s) (you could -f<tag>, or --force)",
                $us, $snags_tripped;
        }
     }
     $snags_summarised = $snags_forced + $snags_tripped;
 }
+sub snags_maybe_bail_early () {
+    # useful to bail out early without doing a lot of work;
+    # not a substitute for snags_maybe_bail.
+    snags_maybe_bail() if $snags_tripped && !$opt_force;
+}
 sub any_snags () {
     return $snags_forced || $snags_tripped;
 }
@@ -980,24 +987,27 @@ sub ffq_prev_branchinfo () {
     return gdr_ffq_prev_branchinfo($current);
 }
 
-sub record_ffq_prev_deferred () {
-    # => ('status', "message")
-    # 'status' may be
-    #    deferred          message is undef
+sub ffq_check ($;$$) {
+    # calls $ff and/or $notff zero or more times
+    # then returns either (status,message) where status is
     #    exists
     #    detached
     #    weird-symref
     #    notbranch
-    # if not ff from some branch we should be ff from, is an snag
-    # if "deferred", will have added something about that to
-    #   @deferred_update_messages, and also maybe printed (already)
-    #   some messages about ff checks
+    # or (undef,undef, $ffq_prev,$gdrlast)
+    # $ff and $notff are called like this:
+    #   $ff->("message for stdout\n");
+    #   $notff->('snag-name', $message);
+    # normally $currentval should be HEAD
+    my ($currentval, $ff, $notff) =@_;
+
+    $ff //= sub { print $_[0] or die $!; };
+    $notff //= \&snag;
+
     my ($status, $message, $current, $ffq_prev, $gdrlast)
        = ffq_prev_branchinfo();
     return ($status, $message) unless $status eq 'branch';
 
-    my $currentval = get_head();
-
     my $exists = git_get_ref $ffq_prev;
     return ('exists',"$ffq_prev already exists") if $exists;
 
@@ -1024,14 +1034,14 @@ sub record_ffq_prev_deferred () {
        return unless length $lrval;
 
        if (is_fast_fwd $lrval, $currentval) {
-           print "OK, you are ahead of $lrref\n" or die $!;
+           $ff->("OK, you are ahead of $lrref\n");
            $checked{$lrref} = 1;
        } elsif (is_fast_fwd $currentval, $lrval) {
            $checked{$lrref} = -1;
-           snag 'behind', "you are behind $lrref, divergence risk";
+           $notff->('behind', "you are behind $lrref, divergence risk");
        } else {
            $checked{$lrref} = -1;
-           snag 'diverged', "you have diverged from $lrref";
+           $notff->('diverged', "you have diverged from $lrref");
        }
     };
 
@@ -1056,6 +1066,25 @@ sub record_ffq_prev_deferred () {
     } elsif ($branch =~ m{^master$}) {
        $check->("refs/remotes/dgit/dgit/sid", 'remote dgit branch for sid');
     }
+    return (undef, undef, $ffq_prev, $gdrlast);
+}
+
+sub record_ffq_prev_deferred () {
+    # => ('status', "message")
+    # 'status' may be
+    #    deferred          message is undef
+    #    exists
+    #    detached
+    #    weird-symref
+    #    notbranch
+    # if not ff from some branch we should be ff from, is an snag
+    # if "deferred", will have added something about that to
+    #   @deferred_update_messages, and also maybe printed (already)
+    #   some messages about ff checks
+    my $currentval = get_head();
+
+    my ($status,$message, $ffq_prev,$gdrlast) = ffq_check $currentval;
+    return ($status,$message) if defined $status;
 
     snags_maybe_bail();
 
@@ -1474,7 +1503,7 @@ sub cmd_status () {
 
 sub cmd_stitch () {
     my $prose = 'stitch';
-    GetOptions('prose=s', \$prose) or die badusage("bad options to stitch");
+    GetOptions('prose=s', \$prose) or badusage("bad options to stitch");
     badusage "no arguments allowed" if @ARGV;
     do_stitch $prose, 0;
 }
@@ -1538,7 +1567,7 @@ sub make_patches ($) {
 sub cmd_make_patches () {
     my $opt_quiet_would_amend;
     GetOptions('quiet-would-amend!', \$opt_quiet_would_amend)
-       or die badusage("bad options to make-patches");
+       or badusage("bad options to make-patches");
     badusage "no arguments allowed" if @ARGV;
     my $old_head = get_head();
     my $new = make_patches $old_head;
@@ -1594,7 +1623,42 @@ sub cmd_convert_from_gbp () {
            "upstream ($upstream) contains debian/ directory";
     }
 
-    snags_maybe_bail();
+    my $previous_dgit_view = eval {
+       my @clogcmd = qw(dpkg-parsechangelog --format rfc822 -n2);
+       my ($lvsn, $suite);
+       parsechangelog_loop \@clogcmd, 'debian/changelog', sub {
+           my ($stz, $desc) = @_;
+           no warnings qw(exiting);
+           printdebug 'CHANGELOG ', Dumper($desc, $stz);
+           next unless $stz->{Date};
+           next unless $stz->{Distribution} ne 'UNRELEASED';
+           $lvsn = $stz->{Version};
+           $suite = $stz->{Distribution};
+           last;
+       };
+       die "neither of the first two changelog entries are released\n"
+           unless defined $lvsn;
+       print "last finished-looking changelog entry: ($lvsn) $suite\n";
+       my $mtag_pat = debiantag_maintview $lvsn, '*';
+       my $mtag = cmdoutput @git, qw(describe --always --abbrev=0 --match),
+           $mtag_pat;
+       die "could not find suitable maintainer view tag $mtag_pat\n"
+           unless $mtag_pat =~ m{/};
+       is_fast_fwd $mtag, 'HEAD' or
+           die "HEAD is not FF from maintainer tag $mtag!";
+       my $dtag = "archive/$mtag";
+       is_fast_fwd $mtag, $dtag or
+           die "dgit view tag $dtag is not FF from maintainer tag $mtag";
+       print "will stitch in dgit view, $dtag\n";
+       git_rev_parse $dtag;
+    };
+    if (!$previous_dgit_view) {
+       $@ =~ s/^\n+//;
+       chomp $@;
+       print STDERR "cannot stitch in dgit view: $@\n";
+    }
+
+    snags_maybe_bail_early();
 
     my $work;
 
@@ -1623,8 +1687,17 @@ sub cmd_convert_from_gbp () {
        runcmd @git, qw(reset --quiet --hard patch-queue/gdr-internal);
        runcmd @git, qw(rebase --quiet --onto), $work, qw(gdr-internal);
        $work = git_rev_parse 'HEAD';
+
+       if ($previous_dgit_view) {
+           $work = make_commit [$work, $previous_dgit_view], [
+ 'git-debrebase import: declare ff from dgit archive view',
+ '[git-debrebase pseudomerge: import-from-gbp]',
+            ];
+       }
     };
 
+    ffq_check $work;
+    snags_maybe_bail();
     update_head_checkout $old_head, $work, 'convert-from-gbp';
 }
 
@@ -1719,7 +1792,7 @@ GetOptions("D+" => \$debuglevel,
               # approach.  '-i=s{0,}' does not work with bundling.
               push @$opt_defaultcmd_interactive, @ARGV;
               @ARGV=();
-          }) or die badusage "bad options\n";
+          }) or badusage "bad options\n";
 initdebug('git-debrebase ');
 enabledebug if $debuglevel;