X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=dgit;h=a168384441455ecbd73c246abea5773da7165529;hb=921e405f6b51d0c9efbe9b7cfd040b276b1194bd;hp=40662b1b2f955b7a50d7804dcf69878d0250e5cf;hpb=04f06d58825cb30e66e1befd198bffaf85c17a9d;p=dgit.git diff --git a/dgit b/dgit index 40662b1b..a1683844 100755 --- 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; @@ -80,15 +80,14 @@ our $rmchanges; our $overwrite_version; # undef: not specified; '': check changelog our $quilt_mode; our $quilt_modes_re = 'linear|smash|auto|nofix|nocheck|gbp|dpm|unapplied'; +our $splitview_mode; +our $splitview_modes_re = qr{auto|always|never}; our $dodep14tag; our %internal_object_save; 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 } @@ -176,11 +175,11 @@ autoflush STDOUT 1; our $supplementary_message = ''; our $made_split_brain = 0; -our $do_split_brain = 0; +our $do_split_brain; # Interactions between quilt mode and split brain # (currently, split brain only implemented iff -# madformat_wantfixup && quiltmode_splitbrain) +# madformat_wantfixup && quiltmode_splitting) # # source format sane `3.0 (quilt)' # madformat_wantfixup() @@ -192,7 +191,7 @@ our $do_split_brain = 0; # # no split no q cache no q cache forbidden, # brain PM on master q fixup on master prevented -# !$do_split_brain PM on master +# !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 @@ -217,11 +216,6 @@ if (!defined $absurdity) { $absurdity =~ s{/[^/]+$}{/absurd} or die; } -sub debiantag ($$) { - my ($v,$distro) = @_; - return $tagformatfn->($v, $distro); -} - sub madformat ($) { $_[0] eq '3.0 (quilt)' } sub lbranch () { return "$branchprefix/$csuite"; } @@ -299,10 +293,12 @@ sub deliberately_not_fast_forward () { } } -sub quiltmode_splitbrain () { +sub quiltmode_splitting () { $quilt_mode =~ m/gbp|dpm|unapplied/; } +sub do_split_brain () { !!($do_split_brain // confess) } + sub opts_opt_multi_cmd { my $extra = shift; my @cmd; @@ -448,7 +444,7 @@ sub branch_is_gdr ($) { # > progress NBYTES # [NBYTES message] # -# > supplementary-message NBYTES # $protovsn >= 3 +# > supplementary-message NBYTES # [NBYTES message] # # main sequence: @@ -468,7 +464,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 @@ -733,7 +729,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', @@ -943,6 +938,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; @@ -960,12 +969,36 @@ sub notpushing () { parseopts_late_defaults(); } +sub determine_whether_split_brain () { + my ($format,) = get_source_format(); + + { + local $access_forpush; + default_from_access_cfg(\$splitview_mode, 'split-view', 'auto', + $splitview_modes_re); + $do_split_brain = 1 if $splitview_mode eq 'always'; + } + + printdebug "format $format, quilt mode $quilt_mode\n"; + + if (madformat_wantfixup($format) && quiltmode_splitting()) { + $splitview_mode ne 'never' or + fail f_ "dgit: quilt mode \`%s' (for format \`%s')". + " implies split view, but split-view set to \`%s'", + $quilt_mode, $format, $splitview_mode; + $do_split_brain = 1; + } + $do_split_brain //= 0; + + return ($format); +} + sub supplementary_message ($) { my ($msg) = @_; 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 "$!"; @@ -1667,58 +1700,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 () { @@ -2133,11 +2114,6 @@ END } } -sub make_commit ($) { - my ($file) = @_; - return cmdoutput @git, qw(hash-object -w -t commit), $file; -} - sub clogp_authline ($) { my ($clogp) = @_; my $author = getfield $clogp, 'Maintainer'; @@ -2549,7 +2525,7 @@ sub generate_commits_from_dsc () { printdebug "import tartree $tt->{F} $tt->{Tree}\n"; my $mbody = f_ "Import %s", $tt->{F}; - $tt->{Commit} = make_commit_text($tt->{Orig} ? <{Commit} = hash_commit_text($tt->{Orig} ? <{Tree} author $r1authline committer $r1authline @@ -2588,14 +2564,14 @@ $changes END close C or confess "$!"; - my $rawimport_hash = make_commit qw(../commit.tmp); + my $rawimport_hash = hash_commit qw(../commit.tmp); if (madformat $dsc->{format}) { printdebug "import apply patches...\n"; # regularise the state of the working tree so that # the checkout of $rawimport_hash works nicely. - my $dappliedcommit = make_commit_text(<('*',access_nomdistro) } - \&debiantag_new, \&debiantag_maintview) - : debiantags('*',access_nomdistro)); + map { "tags/$_" } debiantags('*',access_nomdistro); push @specs, server_branch($csuite); push @specs, $rewritemap; push @specs, qw(heads/*) if deliberately_not_fast_forward; @@ -3449,7 +3421,7 @@ END } close MC or confess "$!"; - $hash = make_commit $mcf; + $hash = hash_commit $mcf; } else { $hash = $mergeinputs[0]{Commit}; } @@ -3810,7 +3782,7 @@ sub fork_for_multisuite ($) { $commit .= "author $authline\n". "committer $authline\n\n"; - $output = make_commit_text $commit.$msg; + $output = hash_commit_text $commit.$msg; printdebug "multisuite merge generated $output\n"; } @@ -4120,6 +4092,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; @@ -4136,7 +4109,7 @@ END return $i_arch_v; } -sub pseudomerge_make_commit ($$$$ $$) { +sub pseudomerge_hash_commit ($$$$ $$) { my ($clogp, $dgitview, $archive_hash, $i_arch_v, $msg_cmd, $msg_msg) = @_; progress f_ "Declaring that HEAD includes all changes in %s...", @@ -4168,7 +4141,7 @@ $msg_msg END close MC or confess "$!"; - return make_commit($pmf); + return hash_commit($pmf); } sub splitbrain_pseudomerge ($$$$) { @@ -4226,7 +4199,7 @@ ENDT } my $arch_v = $i_arch_v->[0]; - my $r = pseudomerge_make_commit + my $r = pseudomerge_hash_commit $clogp, $dgitview, $archive_hash, $i_arch_v, "dgit --quilt=$quilt_mode", (defined $overwrite_version @@ -4250,7 +4223,7 @@ sub plain_overwrite_pseudomerge ($$$) { my $m = f_ "Declare fast forward from %s", $i_arch_v->[0]; - my $r = pseudomerge_make_commit + my $r = pseudomerge_hash_commit $clogp, $head, $archive_hash, $i_arch_v, "dgit", $m; @@ -4275,7 +4248,7 @@ sub push_parse_changelog ($) { if (!$we_are_initiator) { # rpush initiator can't do this because it doesn't have $isuite yet - my $tag = debiantag($cversion, access_nomdistro); + my $tag = debiantag_new($cversion, access_nomdistro); runcmd @git, qw(check-ref-format), $tag; } @@ -4299,7 +4272,7 @@ sub push_tagwants ($$$$) { my ($cversion, $dgithead, $maintviewhead, $tfbase) = @_; my @tagwants; push @tagwants, { - TagFn => \&debiantag, + TagFn => \&debiantag_new, Objid => $dgithead, TfSuffix => '', View => 'dgit', @@ -4311,14 +4284,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 < \&debiantag_maintview, Objid => $dgithead, @@ -4462,14 +4428,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); @@ -4494,7 +4456,7 @@ END my $actualhead = git_rev_parse('HEAD'); if (branch_is_gdr_unstitched_ff($symref, $actualhead, $archive_hash)) { - if (quiltmode_splitbrain()) { + if (quiltmode_splitting()) { my ($ffq_prev, $gdrlast) = branch_gdr_info($symref, $actualhead); fail f_ <= 3; for (;;) { my ($icmd,$iargs) = initiator_expect { @@ -5198,11 +5154,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) { @@ -5272,11 +5223,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'} // ''; - $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$/; @@ -5404,7 +5354,7 @@ sub quiltify_tree_sentinelfiles ($) { return $r; } -sub quiltify_splitbrain ($$$$$$$) { +sub quiltify_splitting ($$$$$$$) { my ($clogp, $unapplied, $headref, $oldtiptree, $diffbits, $editedignores, $cachekey) = @_; my $gitignore_special = 1; @@ -5423,7 +5373,7 @@ sub quiltify_splitbrain ($$$$$$$) { local $ENV{GIT_AUTHOR_EMAIL} = $authline[1]; local $ENV{GIT_AUTHOR_DATE} = $authline[2]; - confess unless $do_split_brain; + confess unless do_split_brain(); my $fulldiffhint = sub { my ($x,$y) = @_; @@ -5510,16 +5460,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 ($$$$) { @@ -5800,8 +5740,6 @@ sub quiltify ($$$$) { runcmd @git, qw(checkout -q), $cc, qw(debian/changelog); } - - runcmd @git, qw(checkout -q master); } sub build_maybe_quilt_fixup () { @@ -5821,7 +5759,7 @@ sub build_maybe_quilt_fixup () { my $splitbrain_cachekey; - if ($do_split_brain) { + if (do_split_brain()) { my $cachehit; ($cachehit, $splitbrain_cachekey) = quilt_check_splitbrain_cache($headref, $upstreamversion); @@ -5832,7 +5770,7 @@ sub build_maybe_quilt_fixup () { } unpack_playtree_need_cd_work($headref); - if ($do_split_brain) { + 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 @@ -5847,13 +5785,26 @@ sub build_maybe_quilt_fixup () { fail f_ "quilt mode %s does not make sense (or is not supported) with single-debian-patch", $quilt_mode - if quiltmode_splitbrain(); + if quiltmode_splitting(); quilt_fixup_singlepatch($clogp, $headref, $upstreamversion); } else { 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; runcmd_ordryrun_local @git, qw(pull --ff-only -q), "$playground/work", qw(master); @@ -5861,13 +5812,6 @@ sub build_maybe_quilt_fixup () { sub build_check_quilt_splitbrain () { build_maybe_quilt_fixup(); - - if ($do_split_brain) { - fail < quiltify_trees_differ($unapplied,$headref, 1, + O2H => quiltify_trees_differ($unapplied,$uheadref, 1, \%editedignores, \@unrepres), - H2A => quiltify_trees_differ($headref, $oldtiptree,1), + H2A => quiltify_trees_differ($uheadref, $oldtiptree,1), O2A => quiltify_trees_differ($unapplied,$oldtiptree,1), }; @@ -6248,9 +6195,9 @@ END $us, $unapplied, $oldtiptree; progress f_ "%s: quilt differences: src: %s orig %s gitignores: %s orig %s\n". -"%s: quilt differences: HEAD %s o+d/p HEAD %s o+d/p", +"%s: quilt differences: %9.00009s %s o+d/p %9.00009s %s o+d/p", $us, $dl[0], $dl[1], $dl[3], $dl[4], - $us, $dl[2], $dl[5]; + $us, $uhead_whatshort, $dl[2], $uhead_whatshort, $dl[5]; if (@unrepres) { print STDERR f_ "dgit: cannot represent change: %s: %s\n", @@ -6279,15 +6226,16 @@ END push @failsuggestion, [ 'origs', __ "Maybe orig tarball(s) are not identical to git representation?" ]; - if (quiltmode_splitbrain()) { - quiltify_splitbrain($clogp, $unapplied, $headref, $oldtiptree, - $diffbits, \%editedignores, - $splitbrain_cachekey); + if (quiltmode_splitting()) { + quiltify_splitting($clogp, $unapplied, $headref, $oldtiptree, + $diffbits, \%editedignores, + $splitbrain_cachekey); return; } 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 "$!"; @@ -6438,13 +6386,11 @@ sub build_or_push_prep_early () { } 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; + my ($format,) = determine_whether_split_brain(); + + fail __ "dgit: --include-dirty is not supported with split view". + " (including with view-splitting quilt modes)" + if do_split_brain() && $includedirty; } sub build_prep_early () { @@ -6772,7 +6718,7 @@ sub build_source { unlink "$buildproductsdir/$sourcechanges" or $!==ENOENT or fail f_ "remove %s: %s", $sourcechanges, $!; } - confess unless !!$made_split_brain == !!$do_split_brain; +# confess unless !!$made_split_brain == do_split_brain(); my @cmd = (@dpkgsource, qw(-b --)); my $leafdir; @@ -7144,7 +7090,7 @@ END my $version = getfield $dsc, 'Version'; my $clogp = commit_getclogp $newhash; my $authline = clogp_authline $clogp; - $newhash = make_commit_text <