X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=dgit.git;a=blobdiff_plain;f=infra%2Fdgit-repos-server;h=1be33609d486578b69a3fdeb2edd7b831b5c9c02;hp=f7d1b045b82c53af39c5144e366b43e65ce223f4;hb=fd18e72ae4857dea79a492c7047af611ece9d1d5;hpb=349b41c2bded6dea53dd947e4ee5c16867b6d055 diff --git a/infra/dgit-repos-server b/infra/dgit-repos-server index f7d1b045..1be33609 100755 --- a/infra/dgit-repos-server +++ b/infra/dgit-repos-server @@ -1,6 +1,23 @@ #!/usr/bin/perl -w # dgit-repos-server # +# git protocol proxy to check dgit pushes etc. +# +# Copyright (C) 2014-2016 Ian Jackson +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + # usages: # dgit-repos-server DISTRO DISTRO-DIR AUTH-SPEC [] --ssh # dgit-repos-server DISTRO DISTRO-DIR AUTH-SPEC [] --cron @@ -34,6 +51,7 @@ use strict; +use Debian::Dgit::Infra; # must precede Debian::Dgit; - can change @INC! use Debian::Dgit qw(:DEFAULT :policyflags); setup_sigwarn(); @@ -445,23 +463,25 @@ sub maybeinstallprospective () { exec qw(git show-ref); die $!; } - my %got = qw(tag 0 head 0); + my %got = qw(newtag 0 omtag 0 head 0); while () { chomp or die; printdebug " show-refs| $_\n"; s/^\S*[1-9a-f]\S* (\S+)$/$1/ or die; next if m{^refs/heads/master$}; my $wh = - m{^refs/tags/} ? 'tag' : + m{^refs/tags/archive/} ? 'newtag' : + m{^refs/tags/} ? 'omtag' : m{^refs/dgit/} ? 'head' : die; + use Data::Dumper; die if $got{$wh}++; } $!=0; $?=0; close SR or $?==256 or die "$? $!"; printdebug "installprospective ?\n"; die Dumper(\%got)." -- missing refs in new repo" - if grep { !$_ } values %got; + unless $got{head} && grep { m/tag$/ && $got{$_} } keys %got; lockrealtree(); @@ -487,21 +507,22 @@ sub main__git_receive_pack () { our ($tagname, $tagval, $suite, $oldcommit, $commit); our ($version, %tagh); +our ($maint_tagname, $maint_tagval); our ($tagexists_error); sub readupdates () { printdebug " updates ...\n"; + my %tags; while () { chomp or die; printdebug " upd.| $_\n"; m/^(\S+) (\S+) (\S+)$/ or die "$_ ?"; my ($old, $sha1, $refname) = ($1, $2, $3); if ($refname =~ m{^refs/tags/(?=(?:archive/)?$distro/)}) { - reject "pushing multiple tags!" if defined $tagname; - $tagname = $'; #'; - $tagval = $sha1; - $tagexists_error= "tag $tagname already exists -". + my $tn = $'; #'; + $tags{$tn} = $sha1; + $tagexists_error= "tag $tn already exists -". " not replacing previously-pushed version" if $old =~ m/[^0]/; } elsif ($refname =~ m{^refs/dgit/}) { @@ -515,7 +536,19 @@ sub readupdates () { } STDIN->error and die $!; - reject "push is missing tag ref update" unless defined $tagname; + reject "push is missing tag ref update" unless %tags; + my @newtags = grep { m#^archive/# } keys %tags; + my @omtags = grep { !m#^archive/# } keys %tags; + reject "pushing too many similar tags" if @newtags>1 || @omtags>1; + if (@newtags) { + ($tagname) = @newtags; + ($maint_tagname) = @omtags; + } else { + ($tagname) = @omtags or die; + } + $tagval = $tags{$tagname}; + $maint_tagval = $tags{$maint_tagname // ''}; + reject "push is missing head ref update" unless defined $suite; printdebug " updates ok.\n"; } @@ -883,6 +916,8 @@ sub onwardpush () { my @cmd = @cmdbase; push @cmd, "$commit:refs/dgit/$suite", "$tagval:refs/tags/$tagname"; + push @cmd, "$maint_tagval:refs/tags/$maint_tagname" + if defined $maint_tagname; debugcmd '+',@cmd; $!=0; my $r = system @cmd;