chiark / gitweb /
test suite: break out t-splitbrain-rm-1-patch
[dgit.git] / dgit
diff --git a/dgit b/dgit
index a6cda1e80ee565de52f944dce7f4e96456d1ca30..6a035d6a2fc8800c4c723ffa3620594870d9c558 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -175,7 +175,7 @@ our $keyid;
 autoflush STDOUT 1;
 
 our $supplementary_message = '';
-our $split_brain = 0;
+our $made_split_brain = 0;
 our $do_split_brain = 0;
 
 # Interactions between quilt mode and split brain
@@ -943,6 +943,20 @@ sub access_forpush () {
     return $access_forpush;
 }
 
+sub default_from_access_cfg ($$$;$) {
+    my ($var, $keybase, $defval, $permit_re) = @_;
+    return if defined $$var;
+
+    $$var = access_cfg("$keybase-newer", 'RETURN-UNDEF');
+    $$var = undef if $$var && $$var !~ m/^$permit_re$/;
+
+    $$var //= access_cfg($keybase, 'RETURN-UNDEF');
+    $$var //= $defval;
+
+    badcfg f_ "unknown %s \`%s'", $keybase, $$var
+       if defined $permit_re and $$var !~ m/$permit_re/;
+}
+
 sub pushing () {
     confess +(__ 'internal error').' '.Dumper($access_forpush)," ?" if
        defined $access_forpush and !$access_forpush;
@@ -4120,6 +4134,7 @@ sub pseudomerge_version_check ($$) {
                $cd = $gf->('Distribution');
            };
            if ($@) {
+                $@ =~ s/^\n//s;
                $@ =~ s/^dgit: //gm;
                fail "$@".
                    f_ "Perhaps debian/changelog does not mention %s ?", $v;
@@ -4489,7 +4504,6 @@ END
     push_parse_dsc($dscpath, $dscfn, $cversion);
 
     my $format = getfield $dsc, 'Format';
-    printdebug "format $format\n";
 
     my $symref = git_get_symref();
     my $actualhead = git_rev_parse('HEAD');
@@ -4515,9 +4529,6 @@ END
 
     if (madformat_wantfixup($format)) {
        # user might have not used dgit build, so maybe do this now:
-       if (quiltmode_splitbrain()) {
-           $do_split_brain = 1;
-       }
        if ($do_split_brain) {
            changedir $playground;
            my $cachekey;
@@ -4535,7 +4546,7 @@ END
        }
     }
     if ($do_split_brain) {
-       $split_brain = 1;
+       $made_split_brain = 1;
        $dgithead = splitbrain_pseudomerge($clogp,
                                           $actualhead, $dgithead,
                                           $archive_hash);
@@ -4569,6 +4580,8 @@ END
        }
     }
 
+    confess unless !!$made_split_brain == !!$do_split_brain;
+
     changedir $playground;
     progress f_ "checking that %s corresponds to HEAD", $dscfn;
     runcmd qw(dpkg-source -x --),
@@ -4582,7 +4595,7 @@ END
     my $r = system @diffcmd;
     if ($r) {
        if ($r==256) {
-           my $referent = $split_brain ? $dgithead : 'HEAD';
+           my $referent = $made_split_brain ? $dgithead : 'HEAD';
            my $diffs = cmdoutput @git, qw(diff --stat), $tree, $dgithead;
 
            my @mode_changes;
@@ -4982,6 +4995,7 @@ sub prep_push () {
     parseopts();
     build_or_push_prep_early();
     pushing();
+    build_or_push_prep_modes();
     check_not_dirty();
     my $specsuite;
     if (@ARGV==0) {
@@ -5424,7 +5438,7 @@ sub quiltify_splitbrain ($$$$$$$) {
     local $ENV{GIT_AUTHOR_EMAIL} = $authline[1];
     local $ENV{GIT_AUTHOR_DATE} =  $authline[2];
 
-    die unless $do_split_brain;
+    confess unless $do_split_brain;
 
     my $fulldiffhint = sub {
        my ($x,$y) = @_;
@@ -5511,16 +5525,6 @@ END
 [dgit ($our_version) update-gitignore-quilt-fixup]
 ENDU
     }
-
-    my $dgitview = git_rev_parse 'HEAD';
-
-    changedir $maindir;
-    reflog_cache_insert "refs/$splitbraincache", $cachekey, $dgitview;
-
-    changedir "$playground/work";
-
-    my $saved = maybe_split_brain_save $headref, $dgitview, __ "converted";
-    progress f_ "dgit view: created (%s)", $saved;
 }
 
 sub quiltify ($$$$) {
@@ -5801,8 +5805,6 @@ sub quiltify ($$$$) {
 
        runcmd @git, qw(checkout -q), $cc, qw(debian/changelog);
     }
-
-    runcmd @git, qw(checkout -q master);
 }
 
 sub build_maybe_quilt_fixup () {
@@ -5812,21 +5814,60 @@ sub build_maybe_quilt_fixup () {
 
     check_for_vendor_patches();
 
-    $do_split_brain = 1 if quiltmode_splitbrain();
-
     my $clogp = parsechangelog();
     my $headref = git_rev_parse('HEAD');
     my $symref = git_get_symref();
+    my $upstreamversion = upstreamversion $version;
 
     prep_ud();
     changedir $playground;
 
-    my $upstreamversion = upstreamversion $version;
+    my $splitbrain_cachekey;
+
+    if ($do_split_brain) {
+       my $cachehit;
+       ($cachehit, $splitbrain_cachekey) =
+           quilt_check_splitbrain_cache($headref, $upstreamversion);
+       if ($cachehit) {
+           changedir $maindir;
+           return;
+       }
+    }
+
+    unpack_playtree_need_cd_work($headref);
+    if ($do_split_brain) {
+       runcmd @git, qw(checkout -q -b dgit-view);
+       # so long as work is not deleted, its current branch will
+       # remain dgit-view, rather than master, so subsequent calls to
+       #  unpack_playtree_need_cd_work
+       # will DTRT, resetting dgit-view.
+       confess if $made_split_brain;
+       $made_split_brain = 1;
+    }
+    chdir '..';
 
     if ($fopts->{'single-debian-patch'}) {
+       fail f_
+ "quilt mode %s does not make sense (or is not supported) with single-debian-patch",
+           $quilt_mode
+           if quiltmode_splitbrain();
        quilt_fixup_singlepatch($clogp, $headref, $upstreamversion);
     } else {
-       quilt_fixup_multipatch($clogp, $headref, $upstreamversion);
+       quilt_fixup_multipatch($clogp, $headref, $upstreamversion,
+                             $splitbrain_cachekey);
+    }
+
+    if ($do_split_brain) {
+       my $dgitview = git_rev_parse 'HEAD';
+
+       changedir $maindir;
+       reflog_cache_insert "refs/$splitbraincache",
+           $splitbrain_cachekey, $dgitview;
+
+       changedir "$playground/work";
+
+       my $saved = maybe_split_brain_save $headref, $dgitview, __ "converted";
+       progress f_ "dgit view: created (%s)", $saved;
     }
 
     changedir $maindir;
@@ -6040,7 +6081,7 @@ sub quilt_check_splitbrain_cache ($$) {
        if ($cachehit ne $headref) {
            progress f_ "dgit view: found cached (%s)", $saved;
            runcmd @git, qw(checkout -q -b dgit-view), $cachehit;
-           $split_brain = 1;
+           $made_split_brain = 1;
            return ($cachehit, $splitbrain_cachekey);
        }
        progress __ "dgit view: found cached, no changes required";
@@ -6052,7 +6093,7 @@ sub quilt_check_splitbrain_cache ($$) {
 }
 
 sub quilt_fixup_multipatch ($$$) {
-    my ($clogp, $headref, $upstreamversion) = @_;
+    my ($clogp, $headref, $upstreamversion, $splitbrain_cachekey) = @_;
 
     progress f_ "examining quilt state (multiple patches, %s mode)",
                $quilt_mode;
@@ -6126,8 +6167,6 @@ sub quilt_fixup_multipatch ($$$) {
     # afterwards with dpkg-source --before-build.  That lets us save a
     # tree object corresponding to .origs.
 
-    my $splitbrain_cachekey;
-
     if ($quilt_mode eq 'linear'
        && branch_is_gdr($headref)) {
        # This is much faster.  It also makes patches that gdr
@@ -6161,12 +6200,6 @@ sub quilt_fixup_multipatch ($$$) {
        chdir '..';
     }
 
-    if (quiltmode_splitbrain()) {
-       my $cachehit;
-       ($cachehit, $splitbrain_cachekey) =
-           quilt_check_splitbrain_cache($headref, $upstreamversion);
-       return if $cachehit;
-    }
     my $unapplied=quilt_fakedsc2unapplied($headref, $upstreamversion);
 
     ensuredir '.pc';
@@ -6262,11 +6295,6 @@ END
     push @failsuggestion, [ 'origs', __
  "Maybe orig tarball(s) are not identical to git representation?" ];
 
-    if ($do_split_brain) {
-       runcmd @git, qw(checkout -q -b dgit-view);
-       die if $split_brain;
-       $split_brain = 1;
-    }
     if (quiltmode_splitbrain()) {
        quiltify_splitbrain($clogp, $unapplied, $headref, $oldtiptree,
                             $diffbits, \%editedignores,
@@ -6276,6 +6304,7 @@ END
 
     progress f_ "starting quiltify (multiple patches, %s mode)", $quilt_mode;
     quiltify($clogp,$headref,$oldtiptree,\@failsuggestion);
+    runcmd @git, qw(checkout -q), (qw(master dgit-view)[!!$do_split_brain]);
 
     if (!open P, '>>', ".pc/applied-patches") {
        $!==&ENOENT or confess "$!";
@@ -6425,9 +6454,20 @@ sub build_or_push_prep_early () {
     $dscfn = dscfn($version);
 }
 
+sub build_or_push_prep_modes () {
+    my ($format,) = get_source_format();
+    printdebug "format $format, quilt mode $quilt_mode\n";
+    if (madformat_wantfixup($format) && quiltmode_splitbrain()) {
+       $do_split_brain = 1;
+    }
+    fail __ "dgit: --include-dirty is not supported in split view quilt mode"
+       if $do_split_brain && $includedirty;
+}
+
 sub build_prep_early () {
     build_or_push_prep_early();
     notpushing();
+    build_or_push_prep_modes();
     check_not_dirty();
 }
 
@@ -6738,7 +6778,7 @@ sub building_source_in_playtree {
     #
     # Note that if we are building a source package in split brain
     # mode we do not support including uncommitted changes, because
-    # that makes quilt fixup too hard.  I.e. ($split_brain && (dgit is
+    # that makes quilt fixup too hard.  I.e. ($made_split_brain && (dgit is
     # building a source package)) => !$includedirty
     return !$includedirty;
 }
@@ -6749,6 +6789,8 @@ sub build_source {
        unlink "$buildproductsdir/$sourcechanges" or $!==ENOENT
            or fail f_ "remove %s: %s", $sourcechanges, $!;
     }
+#    confess unless !!$made_split_brain == !!$do_split_brain;
+
     my @cmd = (@dpkgsource, qw(-b --));
     my $leafdir;
     if (building_source_in_playtree()) {
@@ -6757,9 +6799,9 @@ sub build_source {
         # If we are in split brain, there is already a playtree with
         # the thing we should package into a .dsc (thanks to quilt
         # fixup).  If not, make a playtree
-        prep_ud() unless $split_brain;
+        prep_ud() unless $made_split_brain;
         changedir $playground;
-        unless ($split_brain) {
+        unless ($made_split_brain) {
             my $upstreamversion = upstreamversion $version;
             unpack_playtree_linkorigs($upstreamversion, sub { });
             unpack_playtree_need_cd_work($headref);
@@ -7375,10 +7417,10 @@ sub parseopts () {
            } elsif (m/^--delayed=(\d+)$/s) {
                push @ropts, $_;
                push @dput, $_;
-           } elsif (my ($k,$v) =
-                    m/^--save-(dgit-view)=(.+)$/s ||
+           } elsif (m/^--save-(dgit-view)=(.+)$/s ||
                     m/^--(dgit-view)-save=(.+)$/s
                     ) {
+               my ($k,$v) = ($1,$2);
                push @ropts, $_;
                $v =~ s#^(?!refs/)#refs/heads/#;
                $internal_object_save{$k} = $v;
@@ -7559,19 +7601,10 @@ sub parseopts_late_defaults () {
        $$vr = $v;
     }
 
-    fail __ "dgit: --include-dirty is not supported in split view quilt mode"
-       if $split_brain && $includedirty;
-
-    if (!defined $cleanmode) {
+    {
        local $access_forpush;
-       $cleanmode = access_cfg('clean-mode-newer', 'RETURN-UNDEF');
-       $cleanmode = undef if $cleanmode && $cleanmode !~ m/^$cleanmode_re$/;
-
-       $cleanmode //= access_cfg('clean-mode', 'RETURN-UNDEF');
-       $cleanmode //= 'dpkg-source';
-
-       badcfg f_ "unknown clean-mode \`%s'", $cleanmode unless
-           $cleanmode =~ m/$cleanmode_re/;
+       default_from_access_cfg(\$cleanmode, 'clean-mode', 'dpkg-source',
+                               $cleanmode_re);
     }
 
     $buildproductsdir //= access_cfg('build-products-dir', 'RETURN-UNDEF');