diff options
-rw-r--r-- | debian/changelog | 3 | ||||
-rwxr-xr-x | dgit | 92 |
2 files changed, 85 insertions, 10 deletions
diff --git a/debian/changelog b/debian/changelog index 1cff277..44a0ad9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,7 +3,8 @@ dgit (3.0~) unstable; urgency=medium Protocol change: * Dgit: field now records the nominal distro name, and a hint for a tag and url where the git objects (including any rewrite - map) can be fetched.. + map) can be fetched. + * Use this information, where provided. Closes:#850431. Bugfixes: * dgit config handling: Honour command-line and context-provided @@ -78,6 +78,7 @@ our $patches_applied_dirtily = 00; our $tagformat_want; our $tagformat; our $tagformatfn; +our $chase_dsc_distro=1; #xxx configurable our %forceopts = map { $_=>0 } qw(unrepresentable unsupported-source-format @@ -572,6 +573,10 @@ our %defcfg = ('dgit.default.distro' => 'debian', 'dgit.default.sshpsql-dbname' => 'service=projectb', 'dgit.default.aptget-components' => 'main', 'dgit.default.dgit-tag-format' => 'new,old,maint', + 'dgit.dsc-url-proto-ok.http' => 'true', + 'dgit.dsc-url-proto-ok.https' => 'true', + 'dgit.dsc-url-proto-ok.git' => 'true', + 'dgit.default.dsc-url-proto-ok' => 'false', # 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" @@ -2763,16 +2768,85 @@ sub resolve_dsc_field_commit ($$) { return unless defined $dsc_hash; - my $rewritemapdata = git_cat_file $already_mapref.':map'; - if (defined $rewritemapdata - && $rewritemapdata =~ m/^$dsc_hash(?:[ \t](\w+))/m) { - progress "server's git history rewrite map contains a relevant entry!"; + my $mapref = + $already_distro eq $dsc_distro || !$chase_dsc_distro + ? $already_mapref : undef; - $dsc_hash = $1; - if (defined $dsc_hash) { - progress "using rewritten git hash in place of .dsc value"; - } else { - progress "server data says .dsc hash is to be disregarded"; + my $do_fetch; + $do_fetch = sub { + my ($what, @fetch) = @_; + + local $idistro = $dsc_distro; + my $lrf = lrfetchrefs; + + if (!$chase_dsc_distro) { + progress + "not chasing .dsc distro $dsc_distro: not fetching $what"; + return 0; + } + + progress + ".dsc names distro $dsc_distro: fetching $what"; + + my $url = access_giturl(); + if (!defined $url) { + defined $dsc_hint_url or fail <<END; +.dsc Dgit metadata is in context of distro $dsc_distro +for which we have no configured url and .dsc provides no hint +END + my $proto = + $dsc_hint_url =~ m#^([-+0-9a-zA-Z]+):# ? $1 : + $dsc_hint_url =~ m#^/# ? 'file' : 'bad-syntax'; + parse_cfg_bool "dsc-url-proto-ok", 'false', + cfg("dgit.dsc-url-proto-ok.$proto", + "dgit.default.dsc-url-proto-ok") + or fail <<END; +.dsc Dgit metadata is in context of distro $dsc_distro +for which we have no configured url; +.dsc provices hinted url with protocol $proto which is unsafe. +(can be overridden by config - consult documentation) +END + $url = $dsc_hint_url; + } + + git_lrfetch_sane 1, @fetch; + + return $lrf; + }; + + if (parse_cfg_bool 'rewrite-map-enable', 'true', + access_cfg('rewrite-map-enable', 'RETURN-UNDEF')) { + my $lrf = $do_fetch->("rewrite map", $rewritemap) or return; + $mapref = $lrf.'/'.$rewritemap; + my $rewritemapdata = git_cat_file $mapref.':map'; + if (defined $rewritemapdata + && $rewritemapdata =~ m/^$dsc_hash(?:[ \t](\w+))/m) { + progress + "server's git history rewrite map contains a relevant entry!"; + + $dsc_hash = $1; + if (defined $dsc_hash) { + progress "using rewritten git hash in place of .dsc value"; + } else { + progress "server data says .dsc hash is to be disregarded"; + } + } + } + + if (!defined git_cat_file $dsc_hash) { + my @tags = map { "tags/".$_ } @$dsc_hint_tag; + my $lrf = $do_fetch->("additional commits", @tags) && + defined git_cat_file $dsc_hash + or fail <<END; +.dsc Dgit metadata requires commit $dsc_hash +but we could not obtain that object anywhere. +END + foreach my $t (@tags) { + my $fullrefname = $lrf.'/'.$t; + print STDERR "CHK $t $fullrefname ".Dumper(\%lrfetchrefs_f); + next unless $lrfetchrefs_f{$fullrefname}; + next unless is_fast_fwd "$fullrefname~0", $dsc_hash; + lrfetchref_used $fullrefname; } } } |