chiark / gitweb /
When receiving a push with dgit-repos-server, update the server's refs/heads/master...
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 4 Jul 2015 19:52:42 +0000 (20:52 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 4 Jul 2015 20:40:47 +0000 (21:40 +0100)
debian/changelog
infra/dgit-repos-server

index b798cbd..49b8777 100644 (file)
@@ -58,6 +58,10 @@ dgit (0.23~) unstable; urgency=low
   * Document in manpage under `dgit push' that it is best to build with
     dgit too.  Closes:#763333.
 
+  * When receiving a push with dgit-repos-server, update the server's
+    refs/heads/master if we are pushing to what the distro regards as a
+    relevant branch, and the push would ff master.  Closes:#728209.
+
   * Fix inaccurate error message when archive's git hash is not an
     ancestor of git repo's git hash.
 
index ae25aaa..2d61db9 100755 (executable)
@@ -7,6 +7,7 @@
 # settings
 #   --repos=GIT-REPOS-DIR      default DISTRO-DIR/repos/
 #   --suites=SUITES-FILE       default DISTRO-DIR/suites
+#   --suites-master=SUITES-FILE default DISTRO-DIR/suites-master
 #   --policy-hook=POLICY-HOOK  default DISTRO-DIR/policy-hook
 #   --dgit-live=DGIT-LIVE-DIR  default DISTRO-DIR/dgit-live
 # (DISTRO-DIR is not used other than as default and to pass to policy hook)
 #
 # Works like git-receive-pack
 #
-# SUITES is the name of a file which lists the permissible suites
-# one per line (#-comments and blank lines ignored)
+# SUITES-FILE is the name of a file which lists the permissible suites
+# one per line (#-comments and blank lines ignored).  For --suites-master
+# it is a list of the suite(s) which should, when pushed to, update
+# `master' on the server (if fast forward).
 #
 # AUTH-SPEC is a :-separated list of
 #   KEYRING.GPG,AUTH-SPEC
@@ -181,6 +184,7 @@ our $dgitrepos;
 our $package;
 our $distro;
 our $suitesfile;
+our $suitesformasterfile;
 our $policyhook;
 our $dgitlive;
 our $distrodir;
@@ -413,6 +417,7 @@ sub maybeinstallprospective () {
        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/dgit/} ? 'head' :
@@ -636,17 +641,27 @@ sub verifytag () {
     reject "key not found in keyrings";
 }
 
-sub checksuite () {
-    printdebug "checksuite ($suitesfile)\n";
-    open SUITES, "<", $suitesfile or die $!;
+sub suite_is_in ($) {
+    my ($sf) = @_;
+    printdebug "suite_is_in ($sf)\n";
+    if (!open SUITES, "<", $sf) {
+       $!==ENOENT or die $!;
+       return 0;
+    }
     while (<SUITES>) {
        chomp;
        next unless m/\S/;
        next if m/^\#/;
        s/\s+$//;
-       return if $_ eq $suite;
+       return if $_ eq $suite;
     }
     die $! if SUITES->error;
+    return 0;
+}
+
+sub checksuite () {
+    printdebug "checksuite ($suitesfile)\n";
+    return if suite_is_in $suitesfile;
     reject "unknown suite";
 }
 
@@ -821,14 +836,26 @@ sub checks () {
 }
 
 sub onwardpush () {
-    my @cmd = (qw(git send-pack), $destrepo);
-    push @cmd, qw(--force) if $policy & NOFFCHECK;
+    my @cmdbase = (qw(git send-pack), $destrepo);
+    push @cmdbase, qw(--force) if $policy & NOFFCHECK;
+
+    my @cmd = @cmdbase;
     push @cmd, "$commit:refs/dgit/$suite",
               "$tagval:refs/tags/$tagname";
     debugcmd '+',@cmd;
     $!=0;
     my $r = system @cmd;
     !$r or die "onward push to $destrepo failed: $r $!";
+
+    if (suite_is_in $suitesformasterfile) {
+       @cmd = @cmdbase;
+       push @cmd, "$commit:refs/heads/master";
+       debugcmd '+', @cmd;
+       $!=0; my $r = system @cmd;
+       # tolerate errors (might be not ff)
+       !($r & ~0xff00) or die
+           "onward push to $destrepo#master failed: $r $!";
+    }
 }
 
 sub finalisepush () {
@@ -899,11 +926,12 @@ our %indistrodir = (
     # keys are used for DGIT_DRS_XXX too
     'repos' => \$dgitrepos,
     'suites' => \$suitesfile,
+    'suites-master' => \$suitesformasterfile,
     'policy-hook' => \$policyhook,
     'dgit-live' => \$dgitlive,
     );
 
-our @hookenvs = qw(distro suitesfile policyhook
+our @hookenvs = qw(distro suitesfile suitesformasterfile policyhook
                    dgitlive keyrings dgitrepos distrodir);
 
 # workrepo and destrepo handled ad-hoc