+sub splitbrain_pseudomerge ($$$$) {
+ my ($clogp, $maintview, $dgitview, $archive_hash) = @_;
+ # => $merged_dgitview
+ printdebug "splitbrain_pseudomerge...\n";
+ #
+ # We: debian/PREVIOUS HEAD($maintview)
+ # expect: o ----------------- o
+ # \ \
+ # o o
+ # a/d/PREVIOUS $dgitview
+ # $archive_hash \
+ # If so, \ \
+ # we do: `------------------ o
+ # this: $dgitview'
+ #
+
+ printdebug "splitbrain_pseudomerge...\n";
+
+ my $i_arch_v = pseudomerge_version_check($clogp, $archive_hash);
+
+ return $dgitview unless defined $archive_hash;
+
+ 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 = infopair_lrf_tag_lookup($t_dep14, "maintainer view tag");
+ my $t_dgit = debiantag_new $i_arch_v->[0], access_basedistro;
+ 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";
+
+ infopair_cond_equal($i_dgit, $i_archive);
+ infopair_cond_ff($i_dep14, $i_dgit);
+ $overwrite_version // infopair_cond_ff($i_dep14, [ $maintview, 'HEAD' ]);
+
+ my $r = pseudomerge_make_commit
+ $clogp, $dgitview, $archive_hash, $i_arch_v,
+ "dgit --quilt=$quilt_mode",
+ (defined $overwrite_version ? <<END_OVERWR : <<END_MAKEFF);
+Declare fast forward from $overwrite_version
+END_OVERWR
+Make fast forward from $i_arch_v->[0]
+END_MAKEFF
+
+ 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 { $_->($i_arch_v->[0], 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 $i_arch_v->[0]";
+
+ my $r = pseudomerge_make_commit
+ $clogp, $head, $archive_hash, $i_arch_v,
+ "dgit", $m;
+
+ 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) = @_;
+
+ my $clogp = Dpkg::Control::Hash->new();
+ $clogp->load($clogpfn) or die;
+
+ $package = getfield $clogp, 'Source';
+ my $cversion = getfield $clogp, 'Version';
+ my $tag = debiantag($cversion, access_basedistro);
+ runcmd @git, qw(check-ref-format), $tag;
+
+ my $dscfn = dscfn($cversion);
+
+ return ($clogp, $cversion, $dscfn);
+}
+
+sub push_parse_dsc ($$$) {
+ my ($dscfn,$dscfnwhat, $cversion) = @_;
+ $dsc = parsecontrol($dscfn,$dscfnwhat);
+ my $dversion = getfield $dsc, 'Version';
+ my $dscpackage = getfield $dsc, 'Source';
+ ($dscpackage eq $package && $dversion eq $cversion) or
+ fail "$dscfn is for $dscpackage $dversion".
+ " but debian/changelog is for $package $cversion";
+}
+
+sub push_tagwants ($$$$) {
+ my ($cversion, $dgithead, $maintviewhead, $tfbase) = @_;
+ my @tagwants;
+ push @tagwants, {
+ TagFn => \&debiantag,
+ Objid => $dgithead,
+ 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]; };
+ }
+ printdebug 'push_tagwants: ', Dumper(\@_, \@tagwants);
+ return @tagwants;
+}
+
+sub push_mktags ($$ $$ $) {
+ my ($clogp,$dscfn,