summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Jackson <ijackson@chiark.greenend.org.uk>2015-03-21 12:04:01 +0000
committerIan Jackson <ijackson@chiark.greenend.org.uk>2015-03-22 15:19:51 +0000
commit5408b0c227d942af55442389894a9ed7338a55ce (patch)
tree3b51298221c339945afbf47ae3266973dcc987b2
parente4b24f2532291565f77e120fbc4bff7660b0d115 (diff)
dgit-repos-server: Deal with FRESHREPO from push hook
-rw-r--r--Debian/Dgit.pm2
-rwxr-xr-xinfra/dgit-repos-policy-debian2
-rwxr-xr-xinfra/dgit-repos-server30
3 files changed, 33 insertions, 1 deletions
diff --git a/Debian/Dgit.pm b/Debian/Dgit.pm
index a124930..b934774 100644
--- a/Debian/Dgit.pm
+++ b/Debian/Dgit.pm
@@ -30,7 +30,7 @@ sub NOFFCHECK () { return 2; }
sub FRESHREPO () { return 4; }
# blow away repo right away (ie, as if before push or fetch)
-# ("check-package" only)
+# ("check-package" and "push" only)
sub debiantag ($) {
diff --git a/infra/dgit-repos-policy-debian b/infra/dgit-repos-policy-debian
index 4ba3e8e..493fefd 100755
--- a/infra/dgit-repos-policy-debian
+++ b/infra/dgit-repos-policy-debian
@@ -12,6 +12,8 @@
# cwd for push is a temporary repo where the to-be-pushed objects have
# been received; TAGNAME is the version-based tag
#
+# if push requested FRESHREPO, push-confirm happens in said fresh repo
+#
# policy hook for a particular package will be invoked only once at
# a time
diff --git a/infra/dgit-repos-server b/infra/dgit-repos-server
index ef9f968..5599061 100755
--- a/infra/dgit-repos-server
+++ b/infra/dgit-repos-server
@@ -247,6 +247,7 @@ sub makeworkingclone () {
$workrepo = "$dgitrepos/_tmp/${package}_incoming$$";
acquiretree($workrepo, 1);
runcmd qw(git clone -l -q --mirror), $destrepo, $workrepo;
+ rmtree "${workrepo}_fresh";
}
sub setupstunthook () {
@@ -264,6 +265,15 @@ END
debug " stunt hook set up $prerecv";
}
+sub dealwithfreshrepo () {
+ my $freshrepo = "${workrepo}_fresh";
+ if (!stat $freshrepo) {
+ $!==ENOENT or die "$freshrepo $!";
+ return;
+ }
+ $destrepo = $freshrepo;
+}
+
sub maybeinstallprospective () {
return if $destrepo eq $realdestrepo;
@@ -303,6 +313,8 @@ sub maybeinstallprospective () {
die Dumper(\%got)." -- missing refs in new repo"
if grep { !$_ } values %got;
+ movetogarbage; # in case of FRESHREPO
+
debug "install $destrepo => $realdestrepo";
rename $destrepo, $realdestrepo or die $!;
remove "$destrepo.lock" or die $!;
@@ -312,6 +324,7 @@ sub main__git_receive_pack () {
makeworkingclone();
setupstunthook();
runcmd qw(git receive-pack), $workrepo;
+ dealwithfreshrepo();
maybeinstallprospective();
}
@@ -547,6 +560,23 @@ sub checks () {
chomp $mb;
$mb eq $oldcommit or reject "not fast forward on dgit branch";
}
+
+ if ($policy & FRESHREPO) {
+ # This is troublesome. We have been asked by the policy hook
+ # to receive the push into a fresh repo. But of course we
+ # have actually already mostly received the push into the working
+ # repo. (This is unavoidable because the instruction to use a new
+ # repo comes ultimately from the signed tag for the dgit push,
+ # which has to have been received into some repo.)
+ #
+ # So what we do is generate a fresh working repo right now and
+ # push the head and tag into it. The presence of this fresh
+ # working repo is detected by the parent, which responds by
+ # making a fresh master repo from the template.
+
+ $destrepo = "${workrepo}_fresh"; # workrepo lock covers
+ mkrepo_fromtemplate $destrepo;
+ }
}
sub stunthook () {