chiark / gitweb /
Dgit.pm: Tidying up after tag format: Drop debiantag_old
[dgit.git] / dgit
diff --git a/dgit b/dgit
index 97557ce1c3e1c3a4042160a8c2ab99359184330b..66f2470c6be8e7f2054d237d8a92806f0c004ea7 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -53,7 +53,7 @@ use Debian::Dgit;
 our $our_version = 'UNRELEASED'; ###substituted###
 our $absurdity = undef; ###substituted###
 
-our @rpushprotovsn_support = qw(4 3 2); # 4 is new tag format
+our @rpushprotovsn_support = qw(4 5); # 5 drops tag format specification
 our $protovsn;
 
 our $cmd;
@@ -86,9 +86,6 @@ our $we_are_responder;
 our $we_are_initiator;
 our $initiator_tempdir;
 our $patches_applied_dirtily = 00;
-our $tagformat_want;
-our $tagformat;
-our $tagformatfn;
 our $chase_dsc_distro=1;
 
 our %forceopts = map { $_=>0 }
@@ -175,7 +172,31 @@ 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
+# (currently, split brain only implemented iff
+#  madformat_wantfixup && quiltmode_splitbrain)
+#
+#   source format        sane           `3.0 (quilt)'
+#                                       madformat_wantfixup()
+#
+#   quilt mode                          normal              quiltmode
+#                                       (eg linear)         _splitbrain
+#
+#   ------------      ------------------------------------------------
+#
+#   no split          no q cache        no q cache          forbidden,
+#     brain           PM on master      q fixup on master   prevented
+#   !$do_split_brain                    PM on master
+#
+#   split brain       no q cache        q fixup cached, to dgit view
+#                     PM in dgit view   PM in dgit view
+#
+# PM = pseudomerge to make ff, due to overwrite (or split view)
+# "no q cache" = do not record in cache on build, do not check cache
+# `3.0 (quilt)' with --quilt=nocheck is treated as sane format
 
 END {
     local ($@, $?);
@@ -195,7 +216,7 @@ if (!defined $absurdity) {
 
 sub debiantag ($$) {
     my ($v,$distro) = @_;
-    return $tagformatfn->($v, $distro);
+    return debiantag_new($v, $distro);
 }
 
 sub madformat ($) { $_[0] eq '3.0 (quilt)' }
@@ -424,7 +445,7 @@ sub branch_is_gdr ($) {
 #  > progress NBYTES
 #  [NBYTES message]
 #
-#  > supplementary-message NBYTES          # $protovsn >= 3
+#  > supplementary-message NBYTES
 #  [NBYTES message]
 #
 # main sequence:
@@ -444,7 +465,7 @@ sub branch_is_gdr ($) {
 #
 #  > param head DGIT-VIEW-HEAD
 #  > param csuite SUITE
-#  > param tagformat old|new
+#  > param tagformat new              # $protovsn == 4
 #  > param maint-view MAINT-VIEW-HEAD
 #
 #  > param buildinfo-filename P_V_X.buildinfo   # zero or more times
@@ -709,7 +730,6 @@ our %defcfg = ('dgit.default.distro' => 'debian',
               'dgit.default.archive-query' => 'madison:',
               'dgit.default.sshpsql-dbname' => 'service=projectb',
               'dgit.default.aptget-components' => 'main',
-              'dgit.default.dgit-tag-format' => 'new,old,maint',
               'dgit.default.source-only-uploads' => 'ok',
               'dgit.dsc-url-proto-ok.http'    => 'true',
               'dgit.dsc-url-proto-ok.https'   => 'true',
@@ -919,6 +939,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;
@@ -941,7 +975,7 @@ sub supplementary_message ($) {
     if (!$we_are_responder) {
        $supplementary_message = $msg;
        return;
-    } elsif ($protovsn >= 3) {
+    } else {
        responder_send_command "supplementary-message ".length($msg)
            or confess "$!";
        print PO $msg or confess "$!";
@@ -1643,58 +1677,6 @@ sub archive_query_dummycat ($$) {
 sub file_in_archive_dummycat () { return undef; }
 sub package_not_wholly_new_dummycat () { return undef; }
 
-#---------- tag format handling ----------
-# (untranslated, because everything should be new tag format by now)
-
-sub access_cfg_tagformats () {
-    split /\,/, access_cfg('dgit-tag-format');
-}
-
-sub access_cfg_tagformats_can_splitbrain () {
-    my %y = map { $_ => 1 } access_cfg_tagformats;
-    foreach my $needtf (qw(new maint)) {
-       next if $y{$needtf};
-       return 0;
-    }
-    return 1;
-}
-
-sub need_tagformat ($$) {
-    my ($fmt, $why) = @_;
-    fail "need to use tag format $fmt ($why) but also need".
-       " to use tag format $tagformat_want->[0] ($tagformat_want->[1])".
-       " - no way to proceed"
-       if $tagformat_want && $tagformat_want->[0] ne $fmt;
-    $tagformat_want = [$fmt, $why, $tagformat_want->[2] // 0];
-}
-
-sub select_tagformat () {
-    # sets $tagformatfn
-    return if $tagformatfn && !$tagformat_want;
-    die 'bug' if $tagformatfn && $tagformat_want;
-    # ... $tagformat_want assigned after previous select_tagformat
-
-    my (@supported) = grep { $_ =~ m/^(?:old|new)$/ } access_cfg_tagformats();
-    printdebug "select_tagformat supported @supported\n";
-
-    $tagformat_want //= [ $supported[0], "distro access configuration", 0 ];
-    printdebug "select_tagformat specified @$tagformat_want\n";
-
-    my ($fmt,$why,$override) = @$tagformat_want;
-
-    fail "target distro supports tag formats @supported".
-       " but have to use $fmt ($why)"
-       unless $override
-           or grep { $_ eq $fmt } @supported;
-
-    $tagformat_want = undef;
-    $tagformat = $fmt;
-    $tagformatfn = ${*::}{"debiantag_$fmt"};
-
-    fail "trying to use unknown tag format \`$fmt' ($why) !"
-       unless $tagformatfn;
-}
-
 #---------- archive query entrypoints and rest of program ----------
 
 sub canonicalise_suite () {
@@ -4096,6 +4078,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;
@@ -4287,14 +4270,7 @@ sub push_tagwants ($$$$) {
            TfSuffix => '-maintview',
             View => 'maint',
         };
-    } elsif ($dodep14tag eq 'no' ? 0
-            : $dodep14tag eq 'want' ? access_cfg_tagformats_can_splitbrain
-            : $dodep14tag eq 'always'
-            ? (access_cfg_tagformats_can_splitbrain or fail <<END)
---dep14tag-always (or equivalent in config) means server must support
- both "new" and "maint" tag formats, but config says it doesn't.
-END
-           : die "$dodep14tag ?") {
+    } elsif ($dodep14tag ne 'no') {
        push @tagwants, {
            TagFn => \&debiantag_maintview,
            Objid => $dgithead,
@@ -4438,14 +4414,10 @@ Push failed, while preparing your push.
 You can retry the push, after fixing the problem, if you like.
 END
 
-    need_tagformat 'new', "quilt mode $quilt_mode"
-        if quiltmode_splitbrain;
-
     prep_ud();
 
     access_giturl(); # check that success is vaguely likely
     rpush_handle_protovsn_bothends() if $we_are_initiator;
-    select_tagformat();
 
     my $clogpfn = dgit_privdir()."/changelog.822.tmp";
     runcmd shell_cmd "exec >$clogpfn", qw(dpkg-parsechangelog);
@@ -4465,7 +4437,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');
@@ -4491,9 +4462,8 @@ END
 
     if (madformat_wantfixup($format)) {
        # user might have not used dgit build, so maybe do this now:
-       if (quiltmode_splitbrain()) {
+       if ($do_split_brain) {
            changedir $playground;
-           quilt_make_fake_dsc($upstreamversion);
            my $cachekey;
            ($dgithead, $cachekey) =
                quilt_check_splitbrain_cache($actualhead, $upstreamversion);
@@ -4501,17 +4471,22 @@ END
  "--quilt=%s but no cached dgit view:
  perhaps HEAD changed since dgit build[-source] ?",
                               $quilt_mode;
-           $split_brain = 1;
-           $dgithead = splitbrain_pseudomerge($clogp,
-                                              $actualhead, $dgithead,
-                                              $archive_hash);
-           $maintviewhead = $actualhead;
-           changedir $maindir;
-           prep_ud(); # so _only_subdir() works, below
-       } else {
+       }
+       if (!$do_split_brain) {
+           # In split brain mode, do not attempt to incorporate dirty
+           # stuff from the user's working tree.  That would be mad.
            commit_quilty_patch();
        }
     }
+    if ($do_split_brain) {
+       $made_split_brain = 1;
+       $dgithead = splitbrain_pseudomerge($clogp,
+                                          $actualhead, $dgithead,
+                                          $archive_hash);
+       $maintviewhead = $actualhead;
+       changedir $maindir;
+       prep_ud(); # so _only_subdir() works, below
+    }
 
     if (defined $overwrite_version && !defined $maintviewhead
        && $archive_hash) {
@@ -4538,6 +4513,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 --),
@@ -4551,7 +4528,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;
@@ -4652,10 +4629,8 @@ ENDT
     responder_send_command("param head $dgithead");
     responder_send_command("param csuite $csuite");
     responder_send_command("param isuite $isuite");
-    responder_send_command("param tagformat $tagformat");
+    responder_send_command("param tagformat new"); # needed in $protovsn==4
     if (defined $maintviewhead) {
-       confess "internal error (protovsn=$protovsn)"
-           if defined $protovsn and $protovsn < 4;
        responder_send_command("param maint-view $maintviewhead");
     }
 
@@ -4951,6 +4926,7 @@ sub prep_push () {
     parseopts();
     build_or_push_prep_early();
     pushing();
+    build_or_push_prep_modes();
     check_not_dirty();
     my $specsuite;
     if (@ARGV==0) {
@@ -5024,10 +5000,6 @@ sub cmd_remote_push_responder { cmd_remote_push_build_host(); }
 #     a good error message)
 
 sub rpush_handle_protovsn_bothends () {
-    if ($protovsn < 4) {
-       need_tagformat 'old', "rpush negotiated protocol $protovsn";
-    }
-    select_tagformat();
 }
 
 our $i_tmp;
@@ -5095,7 +5067,6 @@ sub cmd_rpush {
     changedir $i_tmp;
     ($protovsn) = initiator_expect { m/^dgit-remote-push-ready (\S+)/ };
     die "$protovsn ?" unless grep { $_ eq $protovsn } @rpushprotovsn_support;
-    $supplementary_message = '' unless $protovsn >= 3;
 
     for (;;) {
        my ($icmd,$iargs) = initiator_expect {
@@ -5168,11 +5139,6 @@ sub i_resp_want ($) {
     pushing();
     rpush_handle_protovsn_bothends();
 
-    fail f_ "rpush negotiated protocol version %s".
-       " which does not support quilt mode %s",
-       $protovsn, $quilt_mode
-       if quiltmode_splitbrain && $protovsn < 4;
-
     my @localpaths = i_method "i_want", $keyword;
     printdebug "[[  $keyword @localpaths\n";
     foreach my $localpath (@localpaths) {
@@ -5242,11 +5208,10 @@ sub i_want_signed_tag {
     my $maintview = $i_param{'maint-view'};
     die if defined $maintview && $maintview =~ m/[^0-9a-f]/;
 
-    select_tagformat();
-    if ($protovsn >= 4) {
+    if ($protovsn == 4) {
        my $p = $i_param{'tagformat'} // '<undef>';
-       $p eq $tagformat
-           or badproto \*RO, "tag format mismatch: $p vs. $tagformat";
+       $p eq 'new'
+           or badproto \*RO, "tag format mismatch: $p vs. new";
     }
 
     die unless $i_param{'csuite'} =~ m/^$suite_re$/;
@@ -5393,9 +5358,7 @@ sub quiltify_splitbrain ($$$$$$$) {
     local $ENV{GIT_AUTHOR_EMAIL} = $authline[1];
     local $ENV{GIT_AUTHOR_DATE} =  $authline[2];
 
-    die if $split_brain;
-    runcmd @git, qw(checkout -q -b dgit-view);
-    $split_brain = 1;
+    confess unless $do_split_brain;
 
     my $fulldiffhint = sub {
        my ($x,$y) = @_;
@@ -5482,16 +5445,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 ($$$$) {
@@ -5772,8 +5725,6 @@ sub quiltify ($$$$) {
 
        runcmd @git, qw(checkout -q), $cc, qw(debian/changelog);
     }
-
-    runcmd @git, qw(checkout -q master);
 }
 
 sub build_maybe_quilt_fixup () {
@@ -5783,55 +5734,60 @@ sub build_maybe_quilt_fixup () {
 
     check_for_vendor_patches();
 
-    if (quiltmode_splitbrain) {
-       fail <<END unless access_cfg_tagformats_can_splitbrain;
-quilt mode $quilt_mode requires split view so server needs to support
- both "new" and "maint" tag formats, but config says it doesn't.
-END
-    }
-
     my $clogp = parsechangelog();
     my $headref = git_rev_parse('HEAD');
     my $symref = git_get_symref();
-
-    if ($quilt_mode eq 'linear'
-       && !$fopts->{'single-debian-patch'}
-       && branch_is_gdr($headref)) {
-       # This is much faster.  It also makes patches that gdr
-       # likes better for future updates without laundering.
-       #
-       # However, it can fail in some casses where we would
-       # succeed: if there are existing patches, which correspond
-       # to a prefix of the branch, but are not in gbp/gdr
-       # format, gdr will fail (exiting status 7), but we might
-       # be able to figure out where to start linearising.  That
-       # will be slower so hopefully there's not much to do.
-       my @cmd = (@git_debrebase,
-                  qw(--noop-ok -funclean-mixed -funclean-ordering
-                     make-patches --quiet-would-amend));
-       # We tolerate soe snags that gdr wouldn't, by default.
-       if (act_local()) {
-           debugcmd "+",@cmd;
-           $!=0; $?=-1;
-           failedcmd @cmd
-               if system @cmd
-               and not ($? == 7*256 or
-                        $? == -1 && $!==ENOENT);
-       } else {
-           dryrun_report @cmd;
-       }
-       $headref = git_rev_parse('HEAD');
-    }
+    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;
@@ -5839,12 +5795,22 @@ END
         @git, qw(pull --ff-only -q), "$playground/work", qw(master);
 }
 
-sub unpack_playtree_mkwork ($) {
+sub build_check_quilt_splitbrain () {
+    build_maybe_quilt_fixup();
+}
+
+sub unpack_playtree_need_cd_work ($) {
     my ($headref) = @_;
 
-    mkdir "work" or confess "$!";
-    changedir "work";
-    mktree_in_ud_here();
+    # prep_ud() must have been called already.
+    if (!chdir "work") {
+       # Check in the filesystem because sometimes we run prep_ud
+       # in between multiple calls to unpack_playtree_need_cd_work.
+       confess "$!" unless $!==ENOENT;
+       mkdir "work" or confess "$!";
+       changedir "work";
+       mktree_in_ud_here();
+    }
     runcmd @git, qw(reset -q --hard), $headref;
 }
 
@@ -5893,7 +5859,7 @@ sub quilt_fixup_singlepatch ($$$) {
     # necessary to build the source package.
 
     unpack_playtree_linkorigs($upstreamversion, sub { });
-    unpack_playtree_mkwork($headref);
+    unpack_playtree_need_cd_work($headref);
 
     rmtree("debian/patches");
 
@@ -5909,9 +5875,14 @@ sub quilt_fixup_singlepatch ($$$) {
     commit_quilty_patch();
 }
 
-sub quilt_make_fake_dsc ($) {
+sub quilt_need_fake_dsc ($) {
+    # cwd should be playground
     my ($upstreamversion) = @_;
 
+    return if stat_exists "fake.dsc";
+    # ^ OK to test this as a sentinel because if we created it
+    # we must either have done the rest too, or crashed.
+
     my $fakeversion="$upstreamversion-~~DGITFAKE";
 
     my $fakedsc=new IO::File 'fake.dsc', '>' or confess "$!";
@@ -5955,8 +5926,9 @@ END
 sub quilt_fakedsc2unapplied ($$) {
     my ($headref, $upstreamversion) = @_;
     # must be run in the playground
-    # quilt_make_fake_dsc must have been called
+    # quilt_need_fake_dsc must have been called
 
+    quilt_need_fake_dsc($upstreamversion);
     runcmd qw(sh -ec),
         'exec dpkg-source --no-check --skip-patches -x fake.dsc >/dev/null';
 
@@ -5984,6 +5956,8 @@ sub quilt_check_splitbrain_cache ($$) {
     # Computes the cache key and looks in the cache.
     # Returns ($dgit_view_commitid, $cachekey) or (undef, $cachekey)
 
+    quilt_need_fake_dsc($upstreamversion);
+
     my $splitbrain_cachekey;
     
     progress f_
@@ -6015,12 +5989,12 @@ sub quilt_check_splitbrain_cache ($$) {
        "refs/$splitbraincache", $splitbrain_cachekey;
 
     if ($cachehit) {
-       unpack_playtree_mkwork($headref);
+       unpack_playtree_need_cd_work($headref);
        my $saved = maybe_split_brain_save $headref, $cachehit, "cache-hit";
        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";
@@ -6032,7 +6006,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;
@@ -6106,16 +6080,39 @@ 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
+       # likes better for future updates without laundering.
+       #
+       # However, it can fail in some casses where we would
+       # succeed: if there are existing patches, which correspond
+       # to a prefix of the branch, but are not in gbp/gdr
+       # format, gdr will fail (exiting status 7), but we might
+       # be able to figure out where to start linearising.  That
+       # will be slower so hopefully there's not much to do.
 
-    quilt_make_fake_dsc($upstreamversion);
+       unpack_playtree_need_cd_work $headref;
 
-    if (quiltmode_splitbrain()) {
-       my $cachehit;
-       ($cachehit, $splitbrain_cachekey) =
-           quilt_check_splitbrain_cache($headref, $upstreamversion);
-       return if $cachehit;
+       my @cmd = (@git_debrebase,
+                  qw(--noop-ok -funclean-mixed -funclean-ordering
+                     make-patches --quiet-would-amend));
+       # We tolerate soe snags that gdr wouldn't, by default.
+       if (act_local()) {
+           debugcmd "+",@cmd;
+           $!=0; $?=-1;
+           failedcmd @cmd
+               if system @cmd
+               and not ($? == 7*256 or
+                        $? == -1 && $!==ENOENT);
+       } else {
+           dryrun_report @cmd;
+       }
+       $headref = git_rev_parse('HEAD');
+
+       chdir '..';
     }
+
     my $unapplied=quilt_fakedsc2unapplied($headref, $upstreamversion);
 
     ensuredir '.pc';
@@ -6134,7 +6131,7 @@ END
 
     changedir '..';
 
-    unpack_playtree_mkwork($headref);
+    unpack_playtree_need_cd_work($headref);
 
     my $mustdeletepc=0;
     if (stat_exists ".pc") {
@@ -6220,6 +6217,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 "$!";
@@ -6369,9 +6367,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();
 }
 
@@ -6393,7 +6402,7 @@ sub build_prep ($) {
        # said -wc we should still do the check.
        clean_tree_check();
     }
-    build_maybe_quilt_fixup();
+    build_check_quilt_splitbrain();
     if ($rmchanges) {
        my $pat = changespat $version;
        foreach my $f (glob "$buildproductsdir/$pat") {
@@ -6682,7 +6691,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;
 }
@@ -6693,6 +6702,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()) {
@@ -6701,12 +6712,12 @@ 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_mkwork($headref);
+            unpack_playtree_need_cd_work($headref);
             changedir '..';
         }
     } else {
@@ -6773,7 +6784,7 @@ sub cmd_push_source {
        "dgit push-source: --include-dirty/--ignore-dirty does not make".
        "sense with push-source!"
        if $includedirty;
-    build_maybe_quilt_fixup();
+    build_check_quilt_splitbrain();
     if ($changesfile) {
         my $changes = parsecontrol("$buildproductsdir/$changesfile",
                                    __ "source changes file");
@@ -6872,7 +6883,6 @@ sub cmd_print_unapplied_treeish {
     prep_ud();
     changedir $playground;
     my $uv = upstreamversion $version;
-    quilt_make_fake_dsc($uv);
     my $u = quilt_fakedsc2unapplied($headref, $uv);
     print $u, "\n" or confess "$!";
 }
@@ -7320,10 +7330,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;
@@ -7342,11 +7352,6 @@ sub parseopts () {
                    f_ "%s: warning: ignoring unknown force option %s\n",
                       $us, $_;
                $_='';
-           } elsif (m/^--dgit-tag-format=(old|new)$/s) {
-               # undocumented, for testing
-               push @ropts, $_;
-               $tagformat_want = [ $1, 'command line', 1 ];
-               # 1 menas overrides distro configuration
            } elsif (m/^--config-lookup-explode=(.+)$/s) {
                # undocumented, for testing
                push @ropts, $_;
@@ -7504,19 +7509,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');