smart http: use the same connectivity check on cloning
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Sun, 21 Jul 2013 08:18:05 +0000 (15:18 +0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 23 Jul 2013 19:18:18 +0000 (12:18 -0700)
This is an extension of c6807a4 (clone: open a shortcut for
connectivity check - 2013-05-26) to reduce the cost of connectivity
check at clone time, this time with smart http protocol.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-fetch-pack.txt
Documentation/gitremote-helpers.txt
builtin/fetch-pack.c
remote-curl.c
transport-helper.c
index b81e90d8e70722e0da690ab5afa1bca4ad356b68..461a632fb7b25c259e05afc53e9e91df1fb8c3a7 100644 (file)
@@ -90,6 +90,10 @@ be in a separate packet, and the list must end with a flush packet.
 --no-progress::
        Do not show the progress.
 
 --no-progress::
        Do not show the progress.
 
+--check-self-contained-and-connected::
+       Output "connectivity-ok" if the received pack is
+       self-contained and connected.
+
 -v::
        Run verbosely.
 
 -v::
        Run verbosely.
 
index da746419b355a4b5d49b23ed51e3d4aa89d8c2c1..e33bd6a716ca69f89024d90f9bd8795ebece4b72 100644 (file)
@@ -143,6 +143,10 @@ Supported commands: 'list', 'fetch'.
 +
 Supported commands: 'list', 'import'.
 
 +
 Supported commands: 'list', 'import'.
 
+'check-connectivity'::
+       Can guarantee that when a clone is requested, the received
+       pack is self contained and is connected.
+
 If a helper advertises 'connect', Git will use it if possible and
 fall back to another capability if the helper requests so when
 connecting (see the 'connect' command under COMMANDS).
 If a helper advertises 'connect', Git will use it if possible and
 fall back to another capability if the helper requests so when
 connecting (see the 'connect' command under COMMANDS).
@@ -270,6 +274,9 @@ Optionally may output a 'lock <file>' line indicating a file under
 GIT_DIR/objects/pack which is keeping a pack until refs can be
 suitably updated.
 +
 GIT_DIR/objects/pack which is keeping a pack until refs can be
 suitably updated.
 +
+If option 'check-connectivity' is requested, the helper must output
+'connectivity-ok' if the clone is self-contained and connected.
++
 Supported if the helper has the "fetch" capability.
 
 'push' +<src>:<dst>::
 Supported if the helper has the "fetch" capability.
 
 'push' +<src>:<dst>::
@@ -416,6 +423,9 @@ set by Git if the remote helper has the 'option' capability.
        must not rely on this option being set before
        connect request occurs.
 
        must not rely on this option being set before
        connect request occurs.
 
+'option check-connectivity' \{'true'|'false'\}::
+       Request the helper to check connectivity of a clone.
+
 SEE ALSO
 --------
 linkgit:git-remote[1]
 SEE ALSO
 --------
 linkgit:git-remote[1]
index aba44655524ff722d90de09760945f5f30088752..3e19d7149e7b15d61cee1220dbb5e1a2277dc290 100644 (file)
@@ -100,6 +100,10 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
                        pack_lockfile_ptr = &pack_lockfile;
                        continue;
                }
                        pack_lockfile_ptr = &pack_lockfile;
                        continue;
                }
+               if (!strcmp("--check-self-contained-and-connected", arg)) {
+                       args.check_self_contained_and_connected = 1;
+                       continue;
+               }
                usage(fetch_pack_usage);
        }
 
                usage(fetch_pack_usage);
        }
 
@@ -152,6 +156,11 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
                printf("lock %s\n", pack_lockfile);
                fflush(stdout);
        }
                printf("lock %s\n", pack_lockfile);
                fflush(stdout);
        }
+       if (args.check_self_contained_and_connected &&
+           args.self_contained_and_connected) {
+               printf("connectivity-ok\n");
+               fflush(stdout);
+       }
        close(fd[0]);
        close(fd[1]);
        if (finish_connect(conn))
        close(fd[0]);
        close(fd[1]);
        if (finish_connect(conn))
index 60eda6308197ad3d0b5957b9ae34e2dc15dfe5cc..c3157e877ba3a56a00fa58fa94f4b2f84fdf6d46 100644 (file)
@@ -15,6 +15,7 @@ struct options {
        int verbosity;
        unsigned long depth;
        unsigned progress : 1,
        int verbosity;
        unsigned long depth;
        unsigned progress : 1,
+               check_self_contained_and_connected : 1,
                followtags : 1,
                dry_run : 1,
                thin : 1;
                followtags : 1,
                dry_run : 1,
                thin : 1;
@@ -66,6 +67,15 @@ static int set_option(const char *name, const char *value)
                        return -1;
                return 0;
        }
                        return -1;
                return 0;
        }
+       else if (!strcmp(name, "check-connectivity")) {
+               if (!strcmp(value, "true"))
+                       options.check_self_contained_and_connected = 1;
+               else if (!strcmp(value, "false"))
+                       options.check_self_contained_and_connected = 0;
+               else
+                       return -1;
+               return 0;
+       }
        else {
                return 1 /* unsupported */;
        }
        else {
                return 1 /* unsupported */;
        }
@@ -653,7 +663,7 @@ static int fetch_git(struct discovery *heads,
        struct strbuf preamble = STRBUF_INIT;
        char *depth_arg = NULL;
        int argc = 0, i, err;
        struct strbuf preamble = STRBUF_INIT;
        char *depth_arg = NULL;
        int argc = 0, i, err;
-       const char *argv[15];
+       const char *argv[16];
 
        argv[argc++] = "fetch-pack";
        argv[argc++] = "--stateless-rpc";
 
        argv[argc++] = "fetch-pack";
        argv[argc++] = "--stateless-rpc";
@@ -667,6 +677,8 @@ static int fetch_git(struct discovery *heads,
                argv[argc++] = "-v";
                argv[argc++] = "-v";
        }
                argv[argc++] = "-v";
                argv[argc++] = "-v";
        }
+       if (options.check_self_contained_and_connected)
+               argv[argc++] = "--check-self-contained-and-connected";
        if (!options.progress)
                argv[argc++] = "--no-progress";
        if (options.depth) {
        if (!options.progress)
                argv[argc++] = "--no-progress";
        if (options.depth) {
@@ -939,6 +951,7 @@ int main(int argc, const char **argv)
                        printf("fetch\n");
                        printf("option\n");
                        printf("push\n");
                        printf("fetch\n");
                        printf("option\n");
                        printf("push\n");
+                       printf("check-connectivity\n");
                        printf("\n");
                        fflush(stdout);
                } else {
                        printf("\n");
                        fflush(stdout);
                } else {
index 522d79178e2cc4909a5df21fe483946fc3d1ad0e..fe1b7021d70b1014b9e7801c87175f7bf45875e6 100644 (file)
@@ -26,6 +26,7 @@ struct helper_data {
                push : 1,
                connect : 1,
                signed_tags : 1,
                push : 1,
                connect : 1,
                signed_tags : 1,
+               check_connectivity : 1,
                no_disconnect_req : 1;
        char *export_marks;
        char *import_marks;
                no_disconnect_req : 1;
        char *export_marks;
        char *import_marks;
@@ -185,6 +186,8 @@ static struct child_process *get_helper(struct transport *transport)
                        data->bidi_import = 1;
                else if (!strcmp(capname, "export"))
                        data->export = 1;
                        data->bidi_import = 1;
                else if (!strcmp(capname, "export"))
                        data->export = 1;
+               else if (!strcmp(capname, "check-connectivity"))
+                       data->check_connectivity = 1;
                else if (!data->refspecs && !prefixcmp(capname, "refspec ")) {
                        ALLOC_GROW(refspecs,
                                   refspec_nr + 1,
                else if (!data->refspecs && !prefixcmp(capname, "refspec ")) {
                        ALLOC_GROW(refspecs,
                                   refspec_nr + 1,
@@ -346,6 +349,9 @@ static int fetch_with_fetch(struct transport *transport,
        struct strbuf buf = STRBUF_INIT;
 
        standard_options(transport);
        struct strbuf buf = STRBUF_INIT;
 
        standard_options(transport);
+       if (data->check_connectivity &&
+           data->transport_options.check_self_contained_and_connected)
+               set_helper_option(transport, "check-connectivity", "true");
 
        for (i = 0; i < nr_heads; i++) {
                const struct ref *posn = to_fetch[i];
 
        for (i = 0; i < nr_heads; i++) {
                const struct ref *posn = to_fetch[i];
@@ -369,6 +375,10 @@ static int fetch_with_fetch(struct transport *transport,
                        else
                                transport->pack_lockfile = xstrdup(name);
                }
                        else
                                transport->pack_lockfile = xstrdup(name);
                }
+               else if (data->check_connectivity &&
+                        data->transport_options.check_self_contained_and_connected &&
+                        !strcmp(buf.buf, "connectivity-ok"))
+                       data->transport_options.self_contained_and_connected = 1;
                else if (!buf.len)
                        break;
                else
                else if (!buf.len)
                        break;
                else