chiark / gitweb /
Test suite: t-commit: honour $majorv for major version
[dgit.git] / infra / dgit-repos-server
index 92f197b0b001b31bc5dd11907ab7ab1c1359a00f..f7d1b045b82c53af39c5144e366b43e65ce223f4 100755 (executable)
@@ -33,7 +33,9 @@
 # (With --cron AUTH-SPEC is not used and may be the empty string.)
 
 use strict;
-$SIG{__WARN__} = sub { die $_[0]; };
+
+use Debian::Dgit qw(:DEFAULT :policyflags);
+setup_sigwarn();
 
 # DGIT-REPOS-DIR contains:
 # git tree (or other object)      lock (in acquisition order, outer first)
@@ -67,7 +69,7 @@ $SIG{__WARN__} = sub { die $_[0]; };
 #   as a result of this the stunt pre-receive hook runs; it does this:
 #    + understand what refs we are allegedly updating and
 #      check some correspondences:
-#        * we are updating only refs/tags/DISTRO/* and refs/dgit/*
+#        * we are updating only refs/tags/[archive/]DISTRO/* and refs/dgit/*
 #        * and only one of each
 #        * and the tag does not already exist
 #      and
@@ -84,7 +86,7 @@ $SIG{__WARN__} = sub { die $_[0]; };
 #        * the signed tag must refer to a commit
 #        * the signed tag commit must be the refs/dgit value
 #        * the name in the signed tag must correspond to its ref name
-#        * the tag name must be debian/<version> (massaged as needed)
+#        * the tag name must be [archive/]debian/<version> (massaged as needed)
 #        * the suite is one of those permitted
 #        * the signed tag has a suitable name
 #        * run the "push" policy hook
@@ -189,8 +191,6 @@ use Fcntl qw(:flock);
 use File::Path qw(rmtree);
 use File::Temp qw(tempfile);
 
-use Debian::Dgit qw(:DEFAULT :policyflags);
-
 initdebug('');
 
 our $func;
@@ -342,7 +342,8 @@ sub movetogarbage () {
 
     ensuredir "$dgitrepos/_removed-tags";
     open PREVIOUS, ">>", removedtagsfile or die removedtagsfile." $!";
-    git_for_each_ref('refs/tags/'.debiantag('*',$distro), sub {
+    git_for_each_ref([ map { 'refs/tags/'.$_ } debiantags('*',$distro) ],
+                    sub {
        my ($objid,$objtype,$fullrefname,$reftail) = @_;
        print PREVIOUS "\n$objid $reftail .\n" or die $!;
     }, $real);
@@ -496,7 +497,7 @@ sub readupdates () {
        printdebug " upd.| $_\n";
        m/^(\S+) (\S+) (\S+)$/ or die "$_ ?";
        my ($old, $sha1, $refname) = ($1, $2, $3);
-       if ($refname =~ m{^refs/tags/(?=$distro/)}) {
+       if ($refname =~ m{^refs/tags/(?=(?:archive/)?$distro/)}) {
            reject "pushing multiple tags!" if defined $tagname;
            $tagname = $'; #';
            $tagval = $sha1;
@@ -624,7 +625,7 @@ sub dm_txt_check ($$) {
     printdebug " dm_txt_check $keyid $dmtxtfn\n";
     open DT, '<', $dmtxtfn or die "$dmtxtfn $!";
     while (<DT>) {
-       m/^fingerprint:\s+$keyid$/oi
+       m/^fingerprint:\s+\Q$keyid\E$/oi
            ..0 or next;
        if (s/^allow:/ /i..0) {
        } else {
@@ -821,9 +822,16 @@ sub checks () {
     tagh1('object') eq $commit or reject "tag refers to wrong commit";
     tagh1('tag') eq $tagname or reject "tag name in tag is wrong";
 
-    my $expecttagname = debiantag $version, $distro;
-    printdebug "expected tag $expecttagname\n";
-    $tagname eq $expecttagname or die;
+    my @expecttagnames = debiantags($version, $distro);
+    printdebug "expected tag @expecttagnames\n";
+    grep { $tagname eq $_ } @expecttagnames or die;
+
+    foreach my $othertag (grep { $_ ne $tagname } @expecttagnames) {
+       reject "tag $othertag (pushed with differing dgit version)".
+           " already exists -".
+           " not replacing previously-pushed version"
+           if git_get_ref "refs/tags/".$othertag;
+    }
 
     lockrealtree();