use IPC::Open2;
use Digest::SHA;
use Digest::MD5;
+use List::Util qw(any);
use List::MoreUtils qw(pairwise);
use Debian::Dgit;
our $our_version = 'UNRELEASED'; ###substituted###
-our @rpushprotovsn_support = qw(3 2); # 4 is new tag format
+our @rpushprotovsn_support = qw(4 3 2); # 4 is new tag format
our $protovsn;
our $isuite = 'unstable';
return $tagformatfn->($v, $distro);
}
+sub debiantag_maintview ($$) {
+ my ($v,$distro) = @_;
+ $v =~ y/~:/_%/;
+ return "$distro/$v";
+}
+
sub lbranch () { return "$branchprefix/$csuite"; }
my $lbranch_re = '^refs/heads/'.$branchprefix.'/([^/.]+)$';
sub lref () { return "refs/heads/".lbranch(); }
# > file changes
# [etc]
#
-# > param head HEAD
+# > param head DGIT-VIEW-HEAD
# > param csuite SUITE
# > param tagformat old|new
+# > param maint-view MAINT-VIEW-HEAD
#
# > previously REFNAME=OBJNAME # if --deliberately-not-fast-forward
# # goes into tag, for replay prevention
'dgit.default.ssh' => 'ssh',
'dgit.default.archive-query' => 'madison:',
'dgit.default.sshpsql-dbname' => 'service=projectb',
- 'dgit.default.dgit-tag-format' => 'old,new',
+ 'dgit.default.dgit-tag-format' => 'old,new,maint',
'dgit-distro.debian.archive-query' => 'ftpmasterapi:',
'dgit-distro.debian.git-check' => 'url',
'dgit-distro.debian.git-check-suffix' => '/info/refs',
die 'bug' if $tagformatfn && $tagformat_want;
# ... $tagformat_want assigned after previous select_tagformat
- my (@supported) = access_cfg_tagformats();
+ my (@supported) = grep { $_ ne 'maint' } access_cfg_tagformats();
printdebug "select_tagformat supported @supported\n";
$tagformat_want //= [ $supported[0], "distro access configuration", 0 ];
" but debian/changelog is for $package $cversion";
}
-sub push_tagwants ($$$) {
- my ($cversion, $dgithead, $tfbase) = @_;
+sub push_tagwants ($$$$) {
+ my ($cversion, $dgithead, $maintviewhead, $tfbase) = @_;
my @tagwants;
push @tagwants, {
TagFn => \&debiantag,
TfSuffix => '',
View => 'dgit',
};
+ if (defined $maintviewhead) {
+ push @tagwants, {
+ TagFn => \&debiantag_maintview,
+ Objid => $maintviewhead,
+ TfSuffix => '-maintview',
+ View => 'maint',
+ };
+ }
foreach my $tw (@tagwants) {
$tw->{Tag} = $tw->{TagFn}($cversion, access_basedistro);
$tw->{Tfn} = sub { $tfbase.$tw->{TfSuffix}.$_[0]; };
tag $tag
tagger $authline
+END
+ if ($tw->{View} eq 'dgit') {
+ print TO <<END or die $!;
$package release $cversion for $clogsuite ($csuite) [dgit]
[dgit distro=$declaredistro$delibs]
END
- foreach my $ref (sort keys %previously) {
- print TO <<END or die $!;
+ foreach my $ref (sort keys %previously) {
+ print TO <<END or die $!;
[dgit previously:$ref=$previously{$ref}]
END
+ }
+ } elsif ($tw->{View} eq 'maint') {
+ print TO <<END or die $!;
+$package release $cversion for $clogsuite ($csuite)
+(maintainer view tag generated by dgit --quilt=$quilt_mode)
+END
+ } else {
+ die Dumper($tw)."?";
}
close TO or die $!;
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
my $format = getfield $dsc, 'Format';
printdebug "format $format\n";
- my $head = git_rev_parse('HEAD');
+ my $actualhead = git_rev_parse('HEAD');
+ my $dgithead = $actualhead;
+ my $maintviewhead = undef;
if (madformat($format)) {
# user might have not used dgit build, so maybe do this now:
changedir $ud;
quilt_make_fake_dsc($upstreamversion);
my ($dgitview, $cachekey) =
- quilt_check_splitbrain_cache($head, $upstreamversion);
+ quilt_check_splitbrain_cache($actualhead, $upstreamversion);
$dgitview or fail
"--quilt=$quilt_mode but no cached dgit view:
perhaps tree changed since dgit build[-source] ?";
$split_brain = 1;
+ $dgithead = $dgitview;
+ $maintviewhead = $actualhead;
changedir '../../../..';
prep_ud(); # so _only_subdir() works, below
} else {
}
}
- die 'xxx fast forward (should not depend on quilt mode, but will always be needed if we did $split_brain)' if $split_brain;
-
check_not_dirty();
changedir $ud;
progress "checking that $dscfn corresponds to HEAD";
check_for_vendor_patches() if madformat($dsc->{format});
changedir '../../../..';
my $diffopt = $debuglevel>0 ? '--exit-code' : '--quiet';
- my @diffcmd = (@git, qw(diff), $diffopt, $tree);
+ my @diffcmd = (@git, qw(diff), $diffopt, $tree, $dgithead);
debugcmd "+",@diffcmd;
$!=0; $?=-1;
my $r = system @diffcmd;
}
responder_send_file('changes',$changesfile);
- responder_send_command("param head $head");
+ responder_send_command("param head $dgithead");
responder_send_command("param csuite $csuite");
responder_send_command("param tagformat $tagformat");
+ if (quiltmode_splitbrain) {
+ die unless ($protovsn//4) >= 4;
+ responder_send_command("param maint-view $maintviewhead");
+ }
if (deliberately_not_fast_forward) {
git_for_each_ref(lrfetchrefs, sub {
});
}
- my @tagwants = push_tagwants($cversion, $head,
+ my @tagwants = push_tagwants($cversion, $dgithead, $maintviewhead,
".git/dgit/tag");
my @tagobjfns;
my @pushrefs = $forceflag."HEAD:".rrref();
foreach my $tw (@tagwants) {
+ my $view = $tw->{View};
+ next unless $view eq 'dgit'
+ or any { $_ eq $view } access_cfg_tagformats();
push @pushrefs, $forceflag."refs/tags/$tw->{Tag}";
}
runcmd_ordryrun @git, qw(push),access_giturl(), @pushrefs;
- runcmd_ordryrun @git, qw(update-ref -m), 'dgit push', lrref(), 'HEAD';
+ runcmd_ordryrun @git, qw(update-ref -m), 'dgit push', lrref(), $dgithead;
supplementary_message(<<'END');
Push failed, after updating the remote git repository.
($protovsn) = initiator_expect { m/^dgit-remote-push-ready (\S+)/ };
die "$protovsn ?" unless grep { $_ eq $protovsn } @rpushprotovsn_support;
$supplementary_message = '' unless $protovsn >= 3;
+
+ fail "rpush negotiated protocol version $protovsn".
+ " which does not support quilt mode $quilt_mode"
+ if quiltmode_splitbrain;
+
rpush_handle_protovsn_bothends();
for (;;) {
my ($icmd,$iargs) = initiator_expect {
my $head = $i_param{'head'};
die if $head =~ m/[^0-9a-f]/ || $head !~ m/^../;
+ my $maintview = $i_param{'maint-view'};
+ die if defined $maintview && $maintview =~ m/[^0-9a-f]/;
+
select_tagformat();
if ($protovsn >= 4) {
my $p = $i_param{'tagformat'} // '<undef>';
$csuite = $&;
push_parse_dsc $i_dscfn, 'remote dsc', $i_version;
- my @tagwants = push_tagwants $i_version, $head, "tag";
+ my @tagwants = push_tagwants $i_version, $head, $maintview, "tag";
return
push_mktags $i_clogp, $i_dscfn,