chiark / gitweb /
git-cache-proxy: Handle extra-parameters for git protocol v2
authorAnthony PERARD <anthony.perard@citrix.com>
Thu, 22 Jun 2023 14:46:53 +0000 (15:46 +0100)
committerSean Whitton <spwhitton@spwhitton.name>
Thu, 26 Sep 2024 16:01:47 +0000 (17:01 +0100)
This patch allows git clients to communicate with the cache with the git
protocol version 2.

Even though the only described extra-parameters is "version=2", the protocol
describe how extra parameters are handled. `git-upload-pack` will just ignore
the ones it doesn't know about.

The first line of the git protocol is described at
https://github.com/git/git/blob/master/Documentation/gitprotocol-pack.txt
and "extra-parameters" has been implemented here.

These parameters can be passed down to `git-upload-pack` via
the environment variable GIT_PROTOCOL like a clone over ssh would do
(if the ssh server allows GIT_PROTOCOL env variables).

GIT_PROTOCOL is described in
https://github.com/git/git/blob/master/Documentation/git.txt

The reason we need to be able to handle V2 is to allow a shallow clone with an
sha1. Shallow clone seems to only work with a known ref with the v1 of the
protocol.

Example of command that fails when QEMU v8.1 tries to clone the subproject
"dtc" via meson:

    git fetch --depth 1 origin b6910bec11614980a21e46fbccc35934b671bd81

This command also fails when git isn't able to send the envvar GIT_PROTOCOL,
like when cloning over ssh (without git-cache-proxy).

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
scripts/git-cache-proxy

index 2d80cb1b48c1026707b4bd79be0242def7fe9680..13b13e7c501a7a75aa8b7859856f7f37adad449f 100755 (executable)
@@ -244,7 +244,7 @@ sub xread {
 
 chdir $cachedir or fail "chdir $cachedir: $!";
 
-our ($service,$specpath,$spechost,$subdir);
+our ($service,$specpath,$spechost,$extraparams,$subdir);
 our ($tmpd,$gitd,$lock);
 our ($fetch,$url);
 
@@ -259,8 +259,8 @@ sub readcommand () {
     my $hex_len = xread 4;
     fail "Bad hex in packet length" unless $hex_len =~ m|^[0-9a-fA-F]{4}$|;
     my $line = xread -4 + hex $hex_len;
-    unless (($service,$specpath,$spechost) = $line =~
-           m|^(git-[a-z-]+) /*([!-~ ]+)\0host=([!-~]+)\0|) {
+    unless (($service,$specpath,$spechost,$extraparams) = $line =~
+           m|^(git-[a-z-]+) /*([!-~ ]+)\0host=([!-~]+)\0(\0(?:[^\0]+\0)+)?|) {
        $line =~ s|[^ -~]+| |g;
        gitfail "unknown/unsupported instruction `$line'"
     }
@@ -561,6 +561,12 @@ sub runcommand () {
 
     chdir $gitd or fail "chdir $gitd: $!";
 
+    if ($extraparams) {
+        $extraparams =~ s/^\0(.+)\0$/$1/;
+        $extraparams =~ s/\0/:/g;
+        $ENV{GIT_PROTOCOL} = "$extraparams";
+    }
+
     exec qw(git-upload-pack --strict), "--timeout=$servetimeout", qw(.)
        or fail "exec git-upload-pack: $!";
 }