chiark / gitweb /
Switch to new production git repositories for reading. (this can no longer divert...
[dgit.git] / dgit
diff --git a/dgit b/dgit
index e8603ba..ac394f0 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -444,11 +444,15 @@ our %defcfg = ('dgit.default.distro' => 'debian',
               'dgit.default.archive-query' => 'madison:',
               'dgit.default.sshpsql-dbname' => 'service=projectb',
               'dgit-distro.debian.archive-query' => 'ftpmasterapi:',
-              'dgit-distro.debian.git-host' => 'dgit-git.debian.net',
-              'dgit-distro.debian.git-user-force' => 'dgit',
-              'dgit-distro.debian.git-proto' => 'git+ssh://',
-              'dgit-distro.debian.git-path' => '/dgit/debian/repos',
-              'dgit-distro.debian.git-check' => 'ssh-cmd',
+              'dgit-distro.debian.git-check' => 'url',
+              'dgit-distro.debian.git-check-suffix' => '/info/refs',
+              'dgit-distro.debian/push.git-url' => '',
+              'dgit-distro.debian/push.git-host' => 'dgit-git.debian.net',
+              'dgit-distro.debian/push.git-user-force' => 'dgit',
+              'dgit-distro.debian/push.git-proto' => 'git+ssh://',
+              'dgit-distro.debian/push.git-path' => '/dgit/debian/repos',
+              'dgit-distro.debian/push.git-create' => 'true',
+              'dgit-distro.debian/push.git-check' => 'ssh-cmd',
  'dgit-distro.debian.archive-query-url', 'https://api.ftp-master.debian.org/',
 # 'dgit-distro.debian.archive-query-tls-key',
 #    '/etc/ssl/certs/%HOST%.pem:/etc/dgit/%HOST%.pem',
@@ -460,6 +464,9 @@ our %defcfg = ('dgit.default.distro' => 'debian',
 #   '--ca-path=/etc/ssl/ca-debian',
 # ^ this is a workaround but works (only) on DSA-administered machines
               'dgit-distro.debian.diverts.alioth' => '/alioth',
+              'dgit-distro.debian.git-url' => 'https://git.dgit.debian.org',
+              'dgit-distro.debian.git-url-suffix' => '',
+              'dgit-distro.debian/push.diverts.alioth' => '/alioth',
               'dgit-distro.debian/alioth.git-host' => 'git.debian.org',
               'dgit-distro.debian/alioth.git-user-force' => '',
               'dgit-distro.debian/alioth.git-proto' => 'git+ssh://',
@@ -484,20 +491,35 @@ our %defcfg = ('dgit.default.distro' => 'debian',
               'dgit-distro.test-dummy.upload-host' => 'test-dummy',
                );
 
+sub git_get_config ($) {
+    my ($c) = @_;
+
+    our %git_get_config_memo;
+    if (exists $git_get_config_memo{$c}) {
+       return $git_get_config_memo{$c};
+    }
+
+    my $v;
+    my @cmd = (@git, qw(config --), $c);
+    {
+       local ($debuglevel) = $debuglevel-2;
+       $v = cmdoutput_errok @cmd;
+    };
+    if ($?==0) {
+    } elsif ($?==256) {
+       $v = undef;
+    } else {
+       failedcmd @cmd;
+    }
+    $git_get_config_memo{$c} = $v;
+    return $v;
+}
+
 sub cfg {
     foreach my $c (@_) {
        return undef if $c =~ /RETURN-UNDEF/;
-       my @cmd = (@git, qw(config --), $c);
-       my $v;
-       {
-           local ($debuglevel) = $debuglevel-2;
-           $v = cmdoutput_errok @cmd;
-       };
-       if ($?==0) {
-           return $v;
-       } elsif ($?!=256) {
-           failedcmd @cmd;
-       }
+       my $v = git_get_config($c);
+       return $v if defined $v;
        my $dv = $defcfg{$c};
        return $dv if defined $dv;
     }
@@ -532,6 +554,12 @@ sub access_quirk () {
     return ('none',undef);
 }
 
+our $access_pushing = 0;
+
+sub pushing () {
+    $access_pushing = 1;
+}
+
 sub access_distros () {
     # Returns list of distros to try, in order
     #
@@ -545,7 +573,12 @@ sub access_distros () {
     my (undef,$quirkdistro) = access_quirk();
     unshift @l, $quirkdistro;
     unshift @l, $instead_distro;
-    return grep { defined } @l;
+    @l = grep { defined } @l;
+
+    if ($access_pushing) {
+       @l = map { ("$_/push", $_) } @l;
+    }
+    @l;
 }
 
 sub access_cfg (@) {
@@ -618,6 +651,7 @@ sub access_gituserhost () {
 sub access_giturl (;$) {
     my ($optional) = @_;
     my $url = access_cfg('git-url','RETURN-UNDEF');
+    my $suffix;
     if (!defined $url) {
        my $proto = access_cfg('git-proto', 'RETURN-UNDEF');
        return undef unless defined $proto;
@@ -625,8 +659,11 @@ sub access_giturl (;$) {
            $proto.
            access_gituserhost().
            access_cfg('git-path');
+    } else {
+       $suffix = access_cfg('git-url-suffix','RETURN-UNDEF');
     }
-    return "$url/$package.git";
+    $suffix //= '.git';
+    return "$url/$package$suffix";
 }             
 
 sub parsecontrolfh ($$;$) {
@@ -1018,6 +1055,7 @@ sub check_for_git () {
        if ($r =~ m/^divert (\w+)$/) {
            my $divert=$1;
            my ($usedistro,) = access_distros();
+           # NB that if we are pushing, $usedistro will be $distro/push
            $instead_distro= cfg("dgit-distro.$usedistro.diverts.$divert");
            $instead_distro =~ s{^/}{ access_basedistro()."/" }e;
            progress "diverting to $divert (using config for $instead_distro)";
@@ -1025,6 +1063,24 @@ sub check_for_git () {
        }
        failedcmd @cmd unless $r =~ m/^[01]$/;
        return $r+0;
+    } elsif ($how eq 'url') {
+       my $prefix = access_cfg('git-check-url','git-url');
+       my $suffix = access_cfg('git-check-suffix','git-suffix',
+                               'RETURN-UNDEF') // '.git';
+       my $url = "$prefix/$package$suffix";
+       my @cmd = (qw(curl -sS -I), $url);
+       my $result = cmdoutput @cmd;
+       $result =~ m/^\S+ (404|200) /s or
+           fail "unexpected results from git check query - ".
+               Dumper($prefix, $result);
+       my $code = $1;
+       if ($code eq '404') {
+           return 0;
+       } elsif ($code eq '200') {
+           return 1;
+       } else {
+           die;
+       }
     } elsif ($how eq 'true') {
        return 1;
     } elsif ($how eq 'false') {
@@ -1822,7 +1878,6 @@ sub dopush ($) {
     my $tag_obj_hash = cmdoutput @git, qw(hash-object -w -t tag), $tagobjfn;
     runcmd_ordryrun @git, qw(verify-tag), $tag_obj_hash;
     runcmd_ordryrun_local @git, qw(update-ref), "refs/tags/$tag", $tag_obj_hash;
-    runcmd_ordryrun @git, qw(tag -v --), $tag;
 
     if (!check_for_git()) {
        create_remote_git_repo();
@@ -1935,6 +1990,7 @@ sub cmd_pull {
 }
 
 sub cmd_push {
+    pushing();
     parseopts();
     badusage "-p is not allowed with dgit push" if defined $package;
     check_not_dirty();
@@ -1988,6 +2044,7 @@ sub cmd_push {
 #---------- remote commands' implementation ----------
 
 sub cmd_remote_push_build_host {
+    pushing();
     my ($nrargs) = shift @ARGV;
     my (@rargs) = @ARGV[0..$nrargs-1];
     @ARGV = @ARGV[$nrargs..$#ARGV];
@@ -2048,6 +2105,7 @@ sub i_method {
 }
 
 sub cmd_rpush {
+    pushing();
     my $host = nextarg;
     my $dir;
     if ($host =~ m/^((?:[^][]|\[[^][]*\])*)\:/) {
@@ -2633,8 +2691,18 @@ sub quilt_fixup_editor () {
 sub clean_tree () {
     if ($cleanmode eq 'dpkg-source') {
        runcmd_ordryrun_local @dpkgbuildpackage, qw(-T clean);
+    } elsif ($cleanmode eq 'dpkg-source-d') {
+       runcmd_ordryrun_local @dpkgbuildpackage, qw(-d -T clean);
     } elsif ($cleanmode eq 'git') {
        runcmd_ordryrun_local @git, qw(clean -xdf);
+    } elsif ($cleanmode eq 'git-ff') {
+       runcmd_ordryrun_local @git, qw(clean -xdff);
+    } elsif ($cleanmode eq 'check') {
+       my $leftovers = cmdoutput @git, qw(clean -xdn);
+       if (length $leftovers) {
+           print STDERR $leftovers, "\n" or die $!;
+           fail "tree contains uncommitted files and --clean=check specified";
+       }
     } elsif ($cleanmode eq 'none') {
     } else {
        die "$cleanmode ?";
@@ -2729,6 +2797,9 @@ sub build_source {
     if ($cleanmode eq 'dpkg-source') {
        runcmd_ordryrun_local (@dpkgbuildpackage, qw(-us -uc -S)),
            changesopts();
+    } elsif ($cleanmode eq 'dpkg-source-d') {
+       runcmd_ordryrun_local (@dpkgbuildpackage, qw(-us -uc -S -d)),
+           changesopts();
     } else {
        my $pwd = must_getcwd();
        my $leafdir = basename $pwd;
@@ -2871,7 +2942,7 @@ sub parseopts () {
            } elsif (m/^--build-products-dir=(.*)/s) {
                push @ropts, $_;
                $buildproductsdir = $1;
-           } elsif (m/^--clean=(dpkg-source|git|none)$/s) {
+           } elsif (m/^--clean=(dpkg-source(?:-d)?|git|git-ff|check|none)$/s) {
                push @ropts, $_;
                $cleanmode = $1;
            } elsif (m/^--clean=(.*)$/s) {
@@ -2943,9 +3014,18 @@ sub parseopts () {
                } elsif (s/^-wg$//s) {
                    push @ropts, $&;
                    $cleanmode = 'git';
+               } elsif (s/^-wgf$//s) {
+                   push @ropts, $&;
+                   $cleanmode = 'git-ff';
                } elsif (s/^-wd$//s) {
                    push @ropts, $&;
                    $cleanmode = 'dpkg-source';
+               } elsif (s/^-wdd$//s) {
+                   push @ropts, $&;
+                   $cleanmode = 'dpkg-source-d';
+               } elsif (s/^-wc$//s) {
+                   push @ropts, $&;
+                   $cleanmode = 'check';
                } else {
                    badusage "unknown short option \`$_'";
                }