sha1_file: open window into packfiles with O_CLOEXEC
[gitweb.git] / remote-curl.c
index 6b83b7783e9c62fcf623acd0ba034dd1c0b9bd10..f14c41f4c0d6d6c9bbfd18d6417d16f0e6068c1d 100644 (file)
@@ -20,6 +20,8 @@ static struct strbuf url = STRBUF_INIT;
 struct options {
        int verbosity;
        unsigned long depth;
+       char *deepen_since;
+       struct string_list deepen_not;
        unsigned progress : 1,
                check_self_contained_and_connected : 1,
                cloning : 1,
@@ -28,7 +30,8 @@ struct options {
                dry_run : 1,
                thin : 1,
                /* One of the SEND_PACK_PUSH_CERT_* constants. */
-               push_cert : 2;
+               push_cert : 2,
+               deepen_relative : 1;
 };
 static struct options options;
 static struct string_list cas_options = STRING_LIST_INIT_DUP;
@@ -60,6 +63,23 @@ static int set_option(const char *name, const char *value)
                options.depth = v;
                return 0;
        }
+       else if (!strcmp(name, "deepen-since")) {
+               options.deepen_since = xstrdup(value);
+               return 0;
+       }
+       else if (!strcmp(name, "deepen-not")) {
+               string_list_append(&options.deepen_not, value);
+               return 0;
+       }
+       else if (!strcmp(name, "deepen-relative")) {
+               if (!strcmp(value, "true"))
+                       options.deepen_relative = 1;
+               else if (!strcmp(value, "false"))
+                       options.deepen_relative = 0;
+               else
+                       return -1;
+               return 0;
+       }
        else if (!strcmp(name, "followtags")) {
                if (!strcmp(value, "true"))
                        options.followtags = 1;
@@ -725,8 +745,8 @@ static int fetch_dumb(int nr_heads, struct ref **to_fetch)
        int ret, i;
 
        ALLOC_ARRAY(targets, nr_heads);
-       if (options.depth)
-               die("dumb http transport does not support --depth");
+       if (options.depth || options.deepen_since)
+               die("dumb http transport does not support shallow capabilities");
        for (i = 0; i < nr_heads; i++)
                targets[i] = xstrdup(oid_to_hex(&to_fetch[i]->old_oid));
 
@@ -751,38 +771,35 @@ static int fetch_git(struct discovery *heads,
 {
        struct rpc_state rpc;
        struct strbuf preamble = STRBUF_INIT;
-       char *depth_arg = NULL;
-       int argc = 0, i, err;
-       const char *argv[17];
-
-       argv[argc++] = "fetch-pack";
-       argv[argc++] = "--stateless-rpc";
-       argv[argc++] = "--stdin";
-       argv[argc++] = "--lock-pack";
+       int i, err;
+       struct argv_array args = ARGV_ARRAY_INIT;
+
+       argv_array_pushl(&args, "fetch-pack", "--stateless-rpc",
+                        "--stdin", "--lock-pack", NULL);
        if (options.followtags)
-               argv[argc++] = "--include-tag";
+               argv_array_push(&args, "--include-tag");
        if (options.thin)
-               argv[argc++] = "--thin";
-       if (options.verbosity >= 3) {
-               argv[argc++] = "-v";
-               argv[argc++] = "-v";
-       }
+               argv_array_push(&args, "--thin");
+       if (options.verbosity >= 3)
+               argv_array_pushl(&args, "-v", "-v", NULL);
        if (options.check_self_contained_and_connected)
-               argv[argc++] = "--check-self-contained-and-connected";
+               argv_array_push(&args, "--check-self-contained-and-connected");
        if (options.cloning)
-               argv[argc++] = "--cloning";
+               argv_array_push(&args, "--cloning");
        if (options.update_shallow)
-               argv[argc++] = "--update-shallow";
+               argv_array_push(&args, "--update-shallow");
        if (!options.progress)
-               argv[argc++] = "--no-progress";
-       if (options.depth) {
-               struct strbuf buf = STRBUF_INIT;
-               strbuf_addf(&buf, "--depth=%lu", options.depth);
-               depth_arg = strbuf_detach(&buf, NULL);
-               argv[argc++] = depth_arg;
-       }
-       argv[argc++] = url.buf;
-       argv[argc++] = NULL;
+               argv_array_push(&args, "--no-progress");
+       if (options.depth)
+               argv_array_pushf(&args, "--depth=%lu", options.depth);
+       if (options.deepen_since)
+               argv_array_pushf(&args, "--shallow-since=%s", options.deepen_since);
+       for (i = 0; i < options.deepen_not.nr; i++)
+               argv_array_pushf(&args, "--shallow-exclude=%s",
+                                options.deepen_not.items[i].string);
+       if (options.deepen_relative && options.depth)
+               argv_array_push(&args, "--deepen-relative");
+       argv_array_push(&args, url.buf);
 
        for (i = 0; i < nr_heads; i++) {
                struct ref *ref = to_fetch[i];
@@ -795,7 +812,7 @@ static int fetch_git(struct discovery *heads,
 
        memset(&rpc, 0, sizeof(rpc));
        rpc.service_name = "git-upload-pack",
-       rpc.argv = argv;
+       rpc.argv = args.argv;
        rpc.stdin_preamble = &preamble;
        rpc.gzip_request = 1;
 
@@ -804,7 +821,7 @@ static int fetch_git(struct discovery *heads,
                write_or_die(1, rpc.result.buf, rpc.result.len);
        strbuf_release(&rpc.result);
        strbuf_release(&preamble);
-       free(depth_arg);
+       argv_array_clear(&args);
        return err;
 }
 
@@ -998,6 +1015,7 @@ int cmd_main(int argc, const char **argv)
        options.verbosity = 1;
        options.progress = !!isatty(2);
        options.thin = 1;
+       string_list_init(&options.deepen_not, 1);
 
        remote = remote_get(argv[1]);