Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 Documentation/gitremote-helpers.txt |  7 +++++++
 builtin/fetch-pack.c                | 16 +++++++++++++---
 remote-curl.c                       | 30 ++++++++++++++++++++++++++++--
 t/t5536-fetch-shallow.sh            | 27 +++++++++++++++++++++++++++
 transport-helper.c                  |  6 ++++++
 upload-pack.c                       |  2 --
 6 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/Documentation/gitremote-helpers.txt 
b/Documentation/gitremote-helpers.txt
index f1f4ca9..c2908db 100644
--- a/Documentation/gitremote-helpers.txt
+++ b/Documentation/gitremote-helpers.txt
@@ -437,6 +437,13 @@ set by Git if the remote helper has the 'option' 
capability.
 'option check-connectivity' \{'true'|'false'\}::
        Request the helper to check connectivity of a clone.
 
+'option cloning \{'true'|'false'\}::
+       Notify the helper this is a clone request (i.e. the current
+       repository is guaranteed empty).
+
+'option update-shallow \{'true'|'false'\}::
+       Allow to extend .git/shallow if the new refs require it.
+
 SEE ALSO
 --------
 linkgit:git-remote[1]
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index aa6e596..64d1c0e 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -46,6 +46,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char 
*prefix)
        char **pack_lockfile_ptr = NULL;
        struct child_process *conn;
        struct fetch_pack_args args;
+       struct extra_have_objects shallow;
 
        packet_trace_identity("fetch-pack");
 
@@ -113,6 +114,14 @@ int cmd_fetch_pack(int argc, const char **argv, const char 
*prefix)
                        args.check_self_contained_and_connected = 1;
                        continue;
                }
+               if (!strcmp("--cloning", arg)) {
+                       args.cloning = 1;
+                       continue;
+               }
+               if (!strcmp("--update-shallow", arg)) {
+                       args.update_shallow = 1;
+                       continue;
+               }
                usage(fetch_pack_usage);
        }
 
@@ -157,10 +166,11 @@ int cmd_fetch_pack(int argc, const char **argv, const 
char *prefix)
                                   args.verbose ? CONNECT_VERBOSE : 0);
        }
 
-       get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL, NULL);
+       memset(&shallow, 0, sizeof(shallow));
+       get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL, &shallow);
 
-       ref = fetch_pack(&args, fd, conn, ref, dest,
-                        sought, nr_sought, NULL, pack_lockfile_ptr);
+       ref = fetch_pack(&args, fd, conn, ref, dest, sought, nr_sought,
+                        &shallow, pack_lockfile_ptr);
        if (pack_lockfile) {
                printf("lock %s\n", pack_lockfile);
                fflush(stdout);
diff --git a/remote-curl.c b/remote-curl.c
index 25d6730..0ae06b3 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -20,6 +20,8 @@ struct options {
        unsigned long depth;
        unsigned progress : 1,
                check_self_contained_and_connected : 1,
+               cloning : 1,
+               update_shallow : 1,
                followtags : 1,
                dry_run : 1,
                thin : 1;
@@ -88,6 +90,24 @@ static int set_option(const char *name, const char *value)
                strbuf_release(&val);
                return 0;
        }
+       else if (!strcmp(name, "cloning")) {
+               if (!strcmp(value, "true"))
+                       options.cloning = 1;
+               else if (!strcmp(value, "false"))
+                       options.cloning = 0;
+               else
+                       return -1;
+               return 0;
+       }
+       else if (!strcmp(name, "update-shallow")) {
+               if (!strcmp(value, "true"))
+                       options.update_shallow = 1;
+               else if (!strcmp(value, "false"))
+                       options.update_shallow = 0;
+               else
+                       return -1;
+               return 0;
+       }
        else {
                return 1 /* unsupported */;
        }
@@ -99,6 +119,7 @@ struct discovery {
        char *buf;
        size_t len;
        struct ref *refs;
+       struct extra_have_objects shallow;
        unsigned proto_git : 1;
 };
 static struct discovery *last_discovery;
@@ -107,7 +128,7 @@ static struct ref *parse_git_refs(struct discovery *heads, 
int for_push)
 {
        struct ref *list = NULL;
        get_remote_heads(-1, heads->buf, heads->len, &list,
-                        for_push ? REF_NORMAL : 0, NULL, NULL);
+                        for_push ? REF_NORMAL : 0, NULL, &heads->shallow);
        return list;
 }
 
@@ -168,6 +189,7 @@ static void free_discovery(struct discovery *d)
        if (d) {
                if (d == last_discovery)
                        last_discovery = NULL;
+               free(d->shallow.array);
                free(d->buf_alloc);
                free_refs(d->refs);
                free(d);
@@ -688,7 +710,7 @@ static int fetch_git(struct discovery *heads,
        struct strbuf preamble = STRBUF_INIT;
        char *depth_arg = NULL;
        int argc = 0, i, err;
-       const char *argv[16];
+       const char *argv[17];
 
        argv[argc++] = "fetch-pack";
        argv[argc++] = "--stateless-rpc";
@@ -704,6 +726,10 @@ static int fetch_git(struct discovery *heads,
        }
        if (options.check_self_contained_and_connected)
                argv[argc++] = "--check-self-contained-and-connected";
+       if (options.cloning)
+               argv[argc++] = "--cloning";
+       if (options.update_shallow)
+               argv[argc++] = "--update-shallow";
        if (!options.progress)
                argv[argc++] = "--no-progress";
        if (options.depth) {
diff --git a/t/t5536-fetch-shallow.sh b/t/t5536-fetch-shallow.sh
index 95b6313..bc96436 100755
--- a/t/t5536-fetch-shallow.sh
+++ b/t/t5536-fetch-shallow.sh
@@ -163,4 +163,31 @@ EOF
        )
 '
 
+if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then
+       say 'skipping remaining tests, git built without http support'
+       test_done
+fi
+
+LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5536'}
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+test_expect_success 'clone http repository' '
+       git clone --bare --no-local shallow 
"$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
+       git clone $HTTPD_URL/smart/repo.git clone &&
+       (
+       cd clone &&
+       git fsck &&
+       git log --format=%s origin/master >actual &&
+       cat <<EOF >expect &&
+6
+5
+4
+3
+EOF
+       test_cmp expect actual
+       )
+'
+
+stop_httpd
 test_done
diff --git a/transport-helper.c b/transport-helper.c
index 673b7c2..e2b4203 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -360,6 +360,12 @@ static int fetch_with_fetch(struct transport *transport,
            data->transport_options.check_self_contained_and_connected)
                set_helper_option(transport, "check-connectivity", "true");
 
+       if (transport->cloning)
+               set_helper_option(transport, "cloning", "true");
+
+       if (data->transport_options.update_shallow)
+               set_helper_option(transport, "update-shallow", "true");
+
        for (i = 0; i < nr_heads; i++) {
                const struct ref *posn = to_fetch[i];
                if (posn->status & REF_STATUS_UPTODATE)
diff --git a/upload-pack.c b/upload-pack.c
index 28269c7..2d02297 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -836,8 +836,6 @@ int main(int argc, char **argv)
 
        if (!enter_repo(dir, strict))
                die("'%s' does not appear to be a git repository", dir);
-       if (is_repository_shallow() && stateless_rpc)
-               die("attempt to push into a shallow repository");
 
        git_config(upload_pack_config, NULL);
        upload_pack();
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to