'dgit.default.archive-query' => 'madison:',
'dgit.default.sshpsql-dbname' => 'service=projectb',
'dgit.default.dgit-tag-format' => 'old,new,maint',
+ # old means "repo server accepts pushes with old dgit tags"
+ # new means "repo server accepts pushes with new dgit tags"
+ # maint means "repo server accepts split brain pushes"
+ # hist means "repo server may have old pushes without new tag"
+ # ("hist" is implied by "old")
'dgit-distro.debian.archive-query' => 'ftpmasterapi:',
'dgit-distro.debian.git-check' => 'url',
'dgit-distro.debian.git-check-suffix' => '/info/refs',
'dgit-distro.debian.new-private-pushers' => 't',
- 'dgit-distro.debian.dgit-tag-format' => 'old',
+ 'dgit-distro.debian.dgit-tag-format' => 'new',
'dgit-distro.debian/push.git-url' => '',
'dgit-distro.debian/push.git-host' => 'push.dgit.debian.org',
'dgit-distro.debian/push.git-user-force' => 'dgit',
die 'bug' if $tagformatfn && $tagformat_want;
# ... $tagformat_want assigned after previous select_tagformat
- my (@supported) = grep { $_ ne 'maint' } access_cfg_tagformats();
+ my (@supported) = grep { $_ =~ m/^(?:old|new)$/ } access_cfg_tagformats();
printdebug "select_tagformat supported @supported\n";
$tagformat_want //= [ $supported[0], "distro access configuration", 0 ];
return 1;
}
+# An "infopair" is a tuple [ $thing, $what ]
+# (often $thing is a commit hash; $what is a description)
+
+sub infopair_cond_equal ($$) {
+ my ($x,$y) = @_;
+ $x->[0] eq $y->[0] or fail <<END;
+$x->[1] ($x->[0]) not equal to $y->[1] ($y->[0])
+END
+};
+
+sub infopair_lrf_tag_lookup ($$) {
+ my ($tagnames, $what) = @_;
+ # $tagname may be an array ref
+ my @tagnames = ref $tagnames ? @$tagnames : ($tagnames);
+ printdebug "infopair_lrfetchref_tag_lookup $what @tagnames\n";
+ foreach my $tagname (@tagnames) {
+ my $lrefname = lrfetchrefs."/tags/$tagname";
+ my $tagobj = $lrfetchrefs_f{$lrefname};
+ next unless defined $tagobj;
+ printdebug "infopair_lrfetchref_tag_lookup $tagobj $tagname $what\n";
+ return [ git_rev_parse($tagobj), $what ];
+ }
+ fail @tagnames==1 ? <<END : <<END;
+Wanted tag $what (@tagnames) on dgit server, but not found
+END
+Wanted tag $what (one of: @tagnames) on dgit server, but not found
+END
+}
+
+sub infopair_cond_ff ($$) {
+ my ($anc,$desc) = @_;
+ is_fast_fwd($anc->[0], $desc->[0]) or fail <<END;
+$anc->[1] ($anc->[0]) .. $desc->[1] ($desc->[0]) is not fast forward
+END
+};
+
+sub pseudomerge_version_check ($$) {
+ my ($clogp, $archive_hash) = @_;
+
+ my $arch_clogp = commit_getclogp $archive_hash;
+ my $i_arch_v = [ (getfield $arch_clogp, 'Version'),
+ 'version currently in archive' ];
+ if (defined $overwrite_version) {
+ infopair_cond_equal([ $overwrite_version, '--overwrite= version' ],
+ $i_arch_v);
+ }
+
+ printdebug "pseudomerge_version_check i_arch_v @$i_arch_v\n";
+ return $i_arch_v;
+}
+
+sub pseudomerge_make_commit ($$$$$) {
+ my ($clogp, $dgitview, $archive_hash, $i_arch_v, $msg) = @_;
+ progress "Declaring that HEAD inciudes all changes in $i_arch_v->[0]...";
+
+ my $tree = cmdoutput qw(git rev-parse), "${dgitview}:";
+ my $authline = clogp_authline $clogp;
+
+ mkpath '.git/dgit';
+ my $pmf = ".git/dgit/pseudomerge";
+ open MC, ">", $pmf or die "$pmf $!";
+ print MC <<END, $msg or die $!;
+tree $tree
+parent $dgitview
+parent $archive_hash
+author $authline
+commiter $authline
+
+END
+ close MC or die $!;
+
+ return make_commit($pmf);
+}
+
sub splitbrain_pseudomerge ($$$$) {
my ($clogp, $maintview, $dgitview, $archive_hash) = @_;
# => $merged_dgitview
# this: $dgitview'
#
- # We work with tuples [ $thing, $what ]
- # (often $thing is a commit hash; $what is a description)
-
- my $tag_lookup = sub {
- my ($tagname, $what) = @_;
- printdebug "splitbrain_pseudomerge tag_lookup $what\n";
- my $lrefname = lrfetchrefs."/tags/$tagname";
- my $tagobj = $lrfetchrefs_f{$lrefname};
- defined $tagobj or fail <<END;
-Wanted tag $tagname ($what) on dgit server, but not found
-END
- printdebug "splitbrain_pseudomerge tag_lookup $tagobj $what\n";
- return [ git_rev_parse($tagobj), $what ];
- };
-
- my $cond_equal = sub {
- my ($x,$y) = @_;
- $x->[0] eq $y->[0] or fail <<END;
-$x->[1] ($x->[0]) not equal to $y->[1] ($y->[0])
-END
- };
- my $cond_ff = sub {
- my ($anc,$desc) = @_;
- is_fast_fwd($anc->[0], $desc->[0]) or fail <<END;
-$anc->[1] ($anc->[0]) .. $desc->[1] ($desc->[0]) is not fast forward
-END
- };
+ printdebug "splitbrain_pseudomerge...\n";
- my $arch_clogp = commit_getclogp $archive_hash;
- my $i_arch_v = [ (getfield $arch_clogp, 'Version'),
- 'version currently in archive' ];
-
- printdebug "splitbrain_pseudomerge i_arch_v @$i_arch_v\n";
+ my $i_arch_v = pseudomerge_version_check($clogp, $archive_hash);
return $dgitview unless defined $archive_hash;
- if ($overwrite_version) {
- progress "Declaring that HEAD inciudes all changes in archive...";
- progress "Checking that $overwrite_version does so...";
- $cond_equal->([ $overwrite_version, '--overwrite= version' ],
- $i_arch_v);
- } else {
+ if (!defined $overwrite_version) {
progress "Checking that HEAD inciudes all changes in archive...";
}
return $dgitview if is_fast_fwd $archive_hash, $dgitview;
my $t_dep14 = debiantag_maintview $i_arch_v->[0], access_basedistro;
- my $i_dep14 = $tag_lookup->($t_dep14, "maintainer view tag");
+ my $i_dep14 = infopair_lrf_tag_lookup($t_dep14, "maintainer view tag");
my $t_dgit = debiantag_new $i_arch_v->[0], access_basedistro;
- my $i_dgit = $tag_lookup->($t_dgit, "dgit view tag");
+ my $i_dgit = infopair_lrf_tag_lookup($t_dgit, "dgit view tag");
my $i_archive = [ $archive_hash, "current archive contents" ];
printdebug "splitbrain_pseudomerge i_archive @$i_archive\n";
- $cond_equal->($i_dgit, $i_archive);
- $cond_ff->($i_dep14, $i_dgit);
- $overwrite_version or $cond_ff->($i_dep14, [ $maintview, 'HEAD' ]);
-
- my $tree = cmdoutput qw(git rev-parse), "${dgitview}:";
- my $authline = clogp_authline $clogp;
-
- mkpath '.git/dgit';
- my $pmf = ".git/dgit/pseudomerge";
- open MC, ">", $pmf or die "$pmf $!";
- print MC <<END or die $!;
-tree $tree
-parent $dgitview
-parent $archive_hash
-author $authline
-commiter $authline
+ infopair_cond_equal($i_dgit, $i_archive);
+ infopair_cond_ff($i_dep14, $i_dgit);
+ $overwrite_version // infopair_cond_ff($i_dep14, [ $maintview, 'HEAD' ]);
-END
- if ($overwrite_version) {
- print MC <<END;
+ my $r = pseudomerge_make_commit
+ $clogp, $dgitview, $archive_hash, $i_arch_v,
+ (defined $overwrite_version ? <<END_OVERWR : <<END_MAKEFF);
Declare fast forward from $overwrite_version
[dgit --quilt=$quilt_mode --overwrite-version=$overwrite_version]
-END
- } else {
- print MC <<END;
+END_OVERWR
Make fast forward from $i_arch_v->[0]
[dgit --quilt=$quilt_mode]
-END
- }
- close MC or die $!;
+END_MAKEFF
- progress "Making pseudo-merge of $i_arch_v->[0] into dgit view.";
- return make_commit($pmf);
+ progress "Made pseudo-merge of $i_arch_v->[0] into dgit view.";
+ return $r;
}
+sub plain_overwrite_pseudomerge ($$$) {
+ my ($clogp, $head, $archive_hash) = @_;
+
+ printdebug "plain_overwrite_pseudomerge...";
+
+ my $i_arch_v = pseudomerge_version_check($clogp, $archive_hash);
+
+ my @tagformats = access_cfg_tagformats();
+ my @t_overwr =
+ map { $_->($overwrite_version, access_basedistro) }
+ (grep { m/^(?:old|hist)$/ } @tagformats)
+ ? \&debiantags : \&debiantag_new;
+ my $i_overwr = infopair_lrf_tag_lookup \@t_overwr, "previous version tag";
+ my $i_archive = [ $archive_hash, "current archive contents" ];
+
+ infopair_cond_equal($i_overwr, $i_archive);
+
+ return $head if is_fast_fwd $archive_hash, $head;
+
+ my $m = "Declare fast forward from $overwrite_version";
+
+ my $r = pseudomerge_make_commit
+ $clogp, $head, $archive_hash, $i_arch_v, <<END;
+$m
+
+[dgit --overwrite-version=$overwrite_version]
+END
+
+ runcmd @git, qw(update-ref -m), $m, 'HEAD', $r, $head;
+
+ progress "Make pseudo-merge of $i_arch_v->[0] into your HEAD.";
+ return $r;
+}
+
sub push_parse_changelog ($) {
my ($clogpfn) = @_;
}
}
+ if (defined $overwrite_version && !defined $maintviewhead) {
+ $dgithead = plain_overwrite_pseudomerge($clogp,
+ $dgithead,
+ $archive_hash);
+ }
+
check_not_dirty();
my $forceflag = '';
responder_send_command("param head $dgithead");
responder_send_command("param csuite $csuite");
responder_send_command("param tagformat $tagformat");
- if (quiltmode_splitbrain) {
+ if (defined $maintviewhead) {
die unless ($protovsn//4) >= 4;
responder_send_command("param maint-view $maintviewhead");
}
}
fail $msg;
}
+ if ($quilt_mode =~ m/dpm/ &&
+ ($diffbits->{H2A} & 01)) {
+ fail <<END;
+--quilt=$quilt_mode specified, implying patches-applied git tree
+ but git tree differs from result of applying debian/patches to upstream
+END
+ }
if ($quilt_mode =~ m/gbp|unapplied/ &&
($diffbits->{O2A} & 01)) { # some patches
quiltify_splitbrain_needed();
runcmd @git, qw(update-ref refs/heads/dgit-view HEAD);
runcmd @git, qw(checkout -q dgit-view);
}
+ if ($quilt_mode =~ m/gbp|dpm/ &&
+ ($diffbits->{O2A} & 02)) {
+ fail <<END
+--quilt=$quilt_mode specified, implying that HEAD is for use with a
+ tool which does not create patches for changes to upstream
+ .gitignores: but, such patches exist in debian/patches.
+END
+ }
if (($diffbits->{H2O} & 02) && # user has modified .gitignore
!($diffbits->{O2A} & 02)) { # patches do not change .gitignore
quiltify_splitbrain_needed();