+$clogp->{Changes}
+
+# imported by dgit from the archive
+END
+ close C or die $!;
+ print "synthesised git commit from .dsc $clogp->{Version}\n";
+ my $commithash = cmdoutput qw(git hash-object -w -t commit ../commit.tmp);
+ chdir '../../../..' or die $!;
+ cmdoutput qw(git update-ref -m),"dgit synthesise $clogp->{Version}",
+ 'DGIT_ARCHIVE', $commithash;
+ cmdoutput qw(git log -n2), $commithash;
+ # ... gives git a chance to complain if our commit is malformed
+ my $outputhash = $commithash;
+ if (defined $upload_hash) {
+ chdir "$ud/$dir" or die $!;
+ runcmd qw(git reset --hard), $upload_hash;
+ runcmd qw(sh -ec), 'dpkg-parsechangelog >>../changelogold.tmp';
+ my $oldclogp = Dpkg::Control::Hash->new();
+ $oldclogp->parse('../changelogold.tmp','previous changelog') or die;
+ my $vcmp =
+ version_compare_string($oldclogp->{Version}, $clogp->{Version});
+ if ($vcmp < 0) {
+ # git upload/ is earlier vsn than archive, use archive
+ } elsif ($vcmp >= 0) {
+ print STDERR <<END or die $!;
+Version actually in archive: $clogp->{Version} (older)
+Last allegedly pushed/uploaded: $oldclogp->{Version} (newer or same)
+Perhaps the upload is stuck in incoming. Using the version from git.
+END
+ } else {
+ die "version in archive is same as version in git".
+ " to-be-uploaded (upload/) branch but archive".
+ " version hash no commit hash?!\n";
+ }
+ chdir '../../../..' or die $!;
+ }
+ rmtree($ud);
+ return $outputhash;
+}
+
+sub rev_parse ($) {
+ return cmdoutput qw(git rev-parse --), "$_[0]~0";
+}
+
+sub is_fast_fwd ($$) {
+ my ($ancestor,$child) = @_;
+ my $mb = cmdoutput qw(git merge-base), $dsc_hash, $upload_hash;
+ return rev_parse($mb) eq rev_parse($ancestor);
+}
+
+sub fetch_from_archive () {
+ # ensures that rref(uploadbranch()) is what is actually in the archive,
+ # one way or another
+ my $upload_ref = rref(uploadbranch());
+ $!=0; $upload_hash = `git show-ref --heads $upload_ref`;
+ die $! if $!;
+ die $? unless ($?==0 && chomp $upload_hash)
+ or ($?==128 && !length $upload_hash);
+ my $hash;
+ if (defined $dsc_hash) {
+ die "missing git history even though dsc has hash"
+ unless length $upload_hash;
+ $hash = $dsc_hash;
+ } else {
+ $hash = generate_commit_from_dsc();
+ }
+ if (length $upload_hash) {
+ die "not fast forward on last upload branch!".
+ " (archive's version left in DGIT_ARCHIVE)"
+ unless is_fast_fwd($dsc_hash, $upload_hash);
+ }
+ if ($upload_hash ne $hash) {
+ cmdoutput qw(git update-ref -m), 'dgit fetch', $upload_ref, $hash;
+ }