Add logic to serve git-prime-clone to git and http clients.

Do not pass --stateless-rpc and --advertise-refs options to
prime-clone. It is inherently stateless and an 'advertisement'.

Signed-off-by: Kevin Wern <kevin.m.w...@gmail.com>
---
 Documentation/git-daemon.txt       |  7 +++++++
 Documentation/git-http-backend.txt |  7 +++++++
 daemon.c                           |  7 +++++++
 http-backend.c                     | 22 +++++++++++++++++-----
 4 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index a69b361..853faab 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -231,6 +231,13 @@ receive-pack::
        enabled by setting `daemon.receivepack` configuration item to
        `true`.
 
+primeclone::
+       This serves 'git prime-clone' service to clients, allowing
+       'git clone' clients to get the location of a static resource
+       to download and integrate before performing an incremental
+       fetch. It is 'false' by default, but can be enabled by setting
+       it to `true`.
+
 EXAMPLES
 --------
 We assume the following in /etc/services::
diff --git a/Documentation/git-http-backend.txt 
b/Documentation/git-http-backend.txt
index 9268fb6..40be74e 100644
--- a/Documentation/git-http-backend.txt
+++ b/Documentation/git-http-backend.txt
@@ -54,6 +54,13 @@ http.receivepack::
        disabled by setting this item to `false`, or enabled for all
        users, including anonymous users, by setting it to `true`.
 
+http.primeclone::
+       This serves 'git prime-clone' service to clients, allowing
+       'git clone' clients to get the location of a static resource
+       to download and integrate before performing an incremental
+       fetch. It is 'false' by default, but can be enabled by setting
+       it to `true`.
+
 URL TRANSLATION
 ---------------
 To determine the location of the repository on disk, 'git http-backend'
diff --git a/daemon.c b/daemon.c
index 8d45c33..c2f539c 100644
--- a/daemon.c
+++ b/daemon.c
@@ -475,10 +475,17 @@ static int receive_pack(void)
        return run_service_command(argv);
 }
 
+static int prime_clone(void)
+{
+       static const char *argv[] = { "prime-clone", "--strict", ".", NULL };
+       return run_service_command(argv);
+}
+
 static struct daemon_service daemon_service[] = {
        { "upload-archive", "uploadarch", upload_archive, 0, 1 },
        { "upload-pack", "uploadpack", upload_pack, 1, 1 },
        { "receive-pack", "receivepack", receive_pack, 0, 1 },
+       { "prime-clone", "primeclone", prime_clone, 0, 1 },
 };
 
 static void enable_service(const char *name, int ena)
diff --git a/http-backend.c b/http-backend.c
index 8870a26..9c89a10 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -27,6 +27,7 @@ struct rpc_service {
 static struct rpc_service rpc_service[] = {
        { "upload-pack", "uploadpack", 1, 1 },
        { "receive-pack", "receivepack", 0, -1 },
+       { "prime-clone", "primeclone", 0, -1 },
 };
 
 static struct string_list *get_parameters(void)
@@ -450,11 +451,22 @@ static void get_info_refs(char *arg)
        hdr_nocache();
 
        if (service_name) {
-               const char *argv[] = {NULL /* service name */,
-                       "--stateless-rpc", "--advertise-refs",
-                       ".", NULL};
+               struct argv_array argv;
                struct rpc_service *svc = select_service(service_name);
 
+               argv_array_init(&argv);
+               argv_array_push(&argv, svc->name);
+
+               // prime-clone does not need --stateless-rpc and
+               // --advertise-refs options. Maybe it will in the future, but
+               // until then it seems best to do this instead of adding
+               // "dummy" options.
+               if (strcmp(svc->name, "prime-clone") != 0) {
+                       argv_array_pushl(&argv, "--stateless-rpc",
+                                        "--advertise-refs", NULL);
+               }
+
+               argv_array_pushl(&argv, ".", NULL);
                strbuf_addf(&buf, "application/x-git-%s-advertisement",
                        svc->name);
                hdr_str(content_type, buf.buf);
@@ -463,8 +475,8 @@ static void get_info_refs(char *arg)
                packet_write(1, "# service=git-%s\n", svc->name);
                packet_flush(1);
 
-               argv[0] = svc->name;
-               run_service(argv, 0);
+               run_service(argv.argv, 0);
+               argv_array_clear(&argv);
 
        } else {
                select_getanyfile();
-- 
2.7.4

Reply via email to