chiark / gitweb /
dgit: dsc Dgit field handling: Break out resolve_dsc_field_commit
[dgit.git] / dgit
diff --git a/dgit b/dgit
index 54c38c24f534c668b3ecf6e3fccbd62d70cb5c48..933c00824f263b53fd2cebfe18851d6448d93d89 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -727,7 +727,10 @@ sub access_basedistro () {
 
 sub access_nomdistro () {
     my $base = access_basedistro();
-    return cfg("dgit-distro.$base.nominal-distro",'RETURN-UNDEF') // $base;
+    my $r = cfg("dgit-distro.$base.nominal-distro",'RETURN-UNDEF') // $base;
+    $r =~ m/^$distro_re$/ or badcfg
+ "bad syntax for (nominal) distro \`$r' (does not match /^$distro_re$/)";
+    return $r;
 }
 
 sub access_quirk () {
@@ -1680,6 +1683,7 @@ sub create_remote_git_repo () {
 }
 
 our ($dsc_hash,$lastpush_mergeinput);
+our ($dsc_distro, $dsc_hint_tag, $dsc_hint_url);
 
 our $ud = '.git/dgit/unpack';
 
@@ -2700,6 +2704,49 @@ sub fetch_from_archive_record_2 ($) {
     }
 }
 
+sub parse_dsc_field ($$) {
+    my ($dsc, $what) = @_;
+    my $f;
+    foreach my $field (@ourdscfield) {
+       $f = $dsc->{$field};
+       last if defined $f;
+    }
+    if (!defined $f) {
+       progress "$what: NO git hash";
+    } elsif (($dsc_hash, $dsc_distro, $dsc_hint_tag, $dsc_hint_url)
+            = $f =~ m/^(\w+) ($distro_re) ($versiontag_re) (\S+)(?:\s|$)/) {
+       progress "$what: specified git info ($dsc_distro)";
+       $dsc_hint_tag = [ $dsc_hint_tag ];
+    } elsif ($f =~ m/^\w+\s*$/) {
+       $dsc_hash = $&;
+       $dsc_distro //= 'debian';
+       $dsc_hint_tag = [ debiantags +(getfield $dsc, 'Version'),
+                         $dsc_distro ];
+       progress "$what: specified git hash";
+    } else {
+       fail "$what: invalid Dgit info";
+    }
+}
+
+sub resolve_dsc_field_commit ($$) {
+    my ($already_distro, $already_mapref) = @_;
+
+    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!";
+
+       $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";
+       }
+    }
+}
+
 sub fetch_from_archive () {
     ensure_setup_existing_tree();
 
@@ -2711,33 +2758,13 @@ sub fetch_from_archive () {
     get_archive_dsc();
 
     if ($dsc) {
-       foreach my $field (@ourdscfield) {
-           $dsc_hash = $dsc->{$field};
-           last if defined $dsc_hash;
-       }
-       if (defined $dsc_hash) {
-           $dsc_hash =~ m/\w+/ or fail "invalid hash in .dsc \`$dsc_hash'";
-           $dsc_hash = $&;
-           progress "last upload to archive specified git hash";
-       } else {
-           progress "last upload to archive has NO git hash";
-       }
+       parse_dsc_field($dsc, 'last upload to archive');
+       resolve_dsc_field_commit access_basedistro,
+           lrfetchrefs."/".$rewritemap
     } else {
        progress "no version available from the archive";
     }
 
-    my $rewritemapdata = git_cat_file lrfetchrefs."/".$rewritemap.':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 the archive's .dsc has a Dgit field, there are three
     # relevant git commitids we need to choose between and/or merge
     # together:
@@ -5891,31 +5918,30 @@ sub cmd_import_dsc {
 
     parse_dscdata();
 
-    my $dgit_commit = $dsc->{$ourdscfield[0]};
-    if (defined $dgit_commit
+    parse_dsc_field($dsc, "Dgit metadata in .dsc");
+
+    if (defined $dsc_hash
        && !forceing [qw(import-dsc-with-dgit-field)]) {
-       $dgit_commit =~ m/\w+/ or fail "invalid hash in .dsc";
-       $dgit_commit = $&;
        progress "dgit: import-dsc of .dsc with Dgit field, using git hash";
        my @cmd = (qw(sh -ec),
-                  "echo $dgit_commit | git cat-file --batch-check");
+                  "echo $dsc_hash | git cat-file --batch-check");
        my $objgot = cmdoutput @cmd;
        if ($objgot =~ m#^\w+ missing\b#) {
            fail <<END
-.dsc contains Dgit field referring to object $dgit_commit
+.dsc contains Dgit field referring to object $dsc_hash
 Your git tree does not have that object.  Try `git fetch' from a
 plausible server (browse.dgit.d.o? alioth?), and try the import-dsc again.
 END
        }
-       if ($oldhash && !is_fast_fwd $oldhash, $dgit_commit) {
+       if ($oldhash && !is_fast_fwd $oldhash, $dsc_hash) {
            if ($force > 0) {
                progress "Not fast forward, forced update.";
            } else {
-               fail "Not fast forward to $dgit_commit";
+               fail "Not fast forward to $dsc_hash";
            }
        }
        @cmd = (@git, qw(update-ref -m), "dgit import-dsc (Dgit): $info",
-               $dstbranch, $dgit_commit);
+               $dstbranch, $dsc_hash);
        runcmd @cmd;
        progress "dgit: import-dsc updated git ref $dstbranch";
        return 0;