diff options
Diffstat (limited to 'remote-curl.c')
-rw-r--r-- | remote-curl.c | 161 |
1 files changed, 100 insertions, 61 deletions
diff --git a/remote-curl.c b/remote-curl.c index 75532a8bae..32cc4a0c55 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -10,7 +10,7 @@ #include "pkt-line.h" #include "string-list.h" #include "sideband.h" -#include "argv-array.h" +#include "strvec.h" #include "credential.h" #include "oid-array.h" #include "send-pack.h" @@ -39,9 +39,13 @@ struct options { /* One of the SEND_PACK_PUSH_CERT_* constants. */ push_cert : 2, deepen_relative : 1, + + /* see documentation of corresponding flag in fetch-pack.h */ from_promisor : 1, - no_dependents : 1, - atomic : 1; + + atomic : 1, + object_format : 1; + const struct git_hash_algo *hash_algo; }; static struct options options; static struct string_list cas_options = STRING_LIST_INIT_DUP; @@ -119,7 +123,11 @@ static int set_option(const char *name, const char *value) } else if (!strcmp(name, "cas")) { struct strbuf val = STRBUF_INIT; - strbuf_addf(&val, "--" CAS_OPT_NAME "=%s", value); + strbuf_addstr(&val, "--force-with-lease="); + if (*value != '"') + strbuf_addstr(&val, value); + else if (unquote_c_style(&val, value, NULL)) + return -1; string_list_append(&cas_options, val.buf); strbuf_release(&val); return 0; @@ -184,12 +192,19 @@ static int set_option(const char *name, const char *value) } else if (!strcmp(name, "from-promisor")) { options.from_promisor = 1; return 0; - } else if (!strcmp(name, "no-dependents")) { - options.no_dependents = 1; - return 0; } else if (!strcmp(name, "filter")) { options.filter = xstrdup(value); return 0; + } else if (!strcmp(name, "object-format")) { + int algo; + options.object_format = 1; + if (strcmp(value, "true")) { + algo = hash_algo_by_name(value); + if (algo == GIT_HASH_UNKNOWN) + die("unknown object format '%s'", value); + options.hash_algo = &hash_algos[algo]; + } + return 0; } else { return 1 /* unsupported */; } @@ -231,6 +246,7 @@ static struct ref *parse_git_refs(struct discovery *heads, int for_push) case protocol_v0: get_remote_heads(&reader, &list, for_push ? REF_NORMAL : 0, NULL, &heads->shallow); + options.hash_algo = reader.hash_algo; break; case protocol_unknown_version: BUG("unknown protocol version"); @@ -239,6 +255,19 @@ static struct ref *parse_git_refs(struct discovery *heads, int for_push) return list; } +static const struct git_hash_algo *detect_hash_algo(struct discovery *heads) +{ + const char *p = memchr(heads->buf, '\t', heads->len); + int algo; + if (!p) + return the_hash_algo; + + algo = hash_algo_by_length((p - heads->buf) / 2); + if (algo == GIT_HASH_UNKNOWN) + return NULL; + return &hash_algos[algo]; +} + static struct ref *parse_info_refs(struct discovery *heads) { char *data, *start, *mid; @@ -249,6 +278,12 @@ static struct ref *parse_info_refs(struct discovery *heads) struct ref *ref = NULL; struct ref *last_ref = NULL; + options.hash_algo = detect_hash_algo(heads); + if (!options.hash_algo) + die("%sinfo/refs not valid: could not determine hash algorithm; " + "is this a git repository?", + transport_anonymize_url(url.buf)); + data = heads->buf; start = NULL; mid = data; @@ -259,13 +294,13 @@ static struct ref *parse_info_refs(struct discovery *heads) if (data[i] == '\t') mid = &data[i]; if (data[i] == '\n') { - if (mid - start != the_hash_algo->hexsz) + if (mid - start != options.hash_algo->hexsz) die(_("%sinfo/refs not valid: is this a git repository?"), transport_anonymize_url(url.buf)); data[i] = 0; ref_name = mid + 1; ref = alloc_ref(ref_name); - get_oid_hex(start, &ref->old_oid); + get_oid_hex_algop(start, &ref->old_oid, options.hash_algo); if (!refs) refs = ref; if (last_ref) @@ -509,11 +544,16 @@ static struct ref *get_refs(int for_push) static void output_refs(struct ref *refs) { struct ref *posn; + if (options.object_format && options.hash_algo) { + printf(":object-format %s\n", options.hash_algo->name); + } for (posn = refs; posn; posn = posn->next) { if (posn->symref) printf("@%s %s\n", posn->symref, posn->name); else - printf("%s %s\n", oid_to_hex(&posn->old_oid), posn->name); + printf("%s %s\n", hash_to_hex_algop(posn->old_oid.hash, + options.hash_algo), + posn->name); } printf("\n"); fflush(stdout); @@ -1104,41 +1144,39 @@ static int fetch_git(struct discovery *heads, struct rpc_state rpc; struct strbuf preamble = STRBUF_INIT; int i, err; - struct argv_array args = ARGV_ARRAY_INIT; + struct strvec args = STRVEC_INIT; struct strbuf rpc_result = STRBUF_INIT; - argv_array_pushl(&args, "fetch-pack", "--stateless-rpc", - "--stdin", "--lock-pack", NULL); + strvec_pushl(&args, "fetch-pack", "--stateless-rpc", + "--stdin", "--lock-pack", NULL); if (options.followtags) - argv_array_push(&args, "--include-tag"); + strvec_push(&args, "--include-tag"); if (options.thin) - argv_array_push(&args, "--thin"); + strvec_push(&args, "--thin"); if (options.verbosity >= 3) - argv_array_pushl(&args, "-v", "-v", NULL); + strvec_pushl(&args, "-v", "-v", NULL); if (options.check_self_contained_and_connected) - argv_array_push(&args, "--check-self-contained-and-connected"); + strvec_push(&args, "--check-self-contained-and-connected"); if (options.cloning) - argv_array_push(&args, "--cloning"); + strvec_push(&args, "--cloning"); if (options.update_shallow) - argv_array_push(&args, "--update-shallow"); + strvec_push(&args, "--update-shallow"); if (!options.progress) - argv_array_push(&args, "--no-progress"); + strvec_push(&args, "--no-progress"); if (options.depth) - argv_array_pushf(&args, "--depth=%lu", options.depth); + strvec_pushf(&args, "--depth=%lu", options.depth); if (options.deepen_since) - argv_array_pushf(&args, "--shallow-since=%s", options.deepen_since); + strvec_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); + strvec_pushf(&args, "--shallow-exclude=%s", + options.deepen_not.items[i].string); if (options.deepen_relative && options.depth) - argv_array_push(&args, "--deepen-relative"); + strvec_push(&args, "--deepen-relative"); if (options.from_promisor) - argv_array_push(&args, "--from-promisor"); - if (options.no_dependents) - argv_array_push(&args, "--no-dependents"); + strvec_push(&args, "--from-promisor"); if (options.filter) - argv_array_pushf(&args, "--filter=%s", options.filter); - argv_array_push(&args, url.buf); + strvec_pushf(&args, "--filter=%s", options.filter); + strvec_push(&args, url.buf); for (i = 0; i < nr_heads; i++) { struct ref *ref = to_fetch[i]; @@ -1153,12 +1191,12 @@ static int fetch_git(struct discovery *heads, rpc.service_name = "git-upload-pack", rpc.gzip_request = 1; - err = rpc_service(&rpc, heads, args.argv, &preamble, &rpc_result); + err = rpc_service(&rpc, heads, args.v, &preamble, &rpc_result); if (rpc_result.len) write_or_die(1, rpc_result.buf, rpc_result.len); strbuf_release(&rpc_result); strbuf_release(&preamble); - argv_array_clear(&args); + strvec_clear(&args); return err; } @@ -1230,15 +1268,15 @@ static int push_dav(int nr_spec, const char **specs) size_t i; child.git_cmd = 1; - argv_array_push(&child.args, "http-push"); - argv_array_push(&child.args, "--helper-status"); + strvec_push(&child.args, "http-push"); + strvec_push(&child.args, "--helper-status"); if (options.dry_run) - argv_array_push(&child.args, "--dry-run"); + strvec_push(&child.args, "--dry-run"); if (options.verbosity > 1) - argv_array_push(&child.args, "--verbose"); - argv_array_push(&child.args, url.buf); + strvec_push(&child.args, "--verbose"); + strvec_push(&child.args, url.buf); for (i = 0; i < nr_spec; i++) - argv_array_push(&child.args, specs[i]); + strvec_push(&child.args, specs[i]); if (run_command(&child)) die(_("git-http-push failed")); @@ -1249,38 +1287,38 @@ static int push_git(struct discovery *heads, int nr_spec, const char **specs) { struct rpc_state rpc; int i, err; - struct argv_array args; + struct strvec args; struct string_list_item *cas_option; struct strbuf preamble = STRBUF_INIT; struct strbuf rpc_result = STRBUF_INIT; - argv_array_init(&args); - argv_array_pushl(&args, "send-pack", "--stateless-rpc", "--helper-status", - NULL); + strvec_init(&args); + strvec_pushl(&args, "send-pack", "--stateless-rpc", "--helper-status", + NULL); if (options.thin) - argv_array_push(&args, "--thin"); + strvec_push(&args, "--thin"); if (options.dry_run) - argv_array_push(&args, "--dry-run"); + strvec_push(&args, "--dry-run"); if (options.push_cert == SEND_PACK_PUSH_CERT_ALWAYS) - argv_array_push(&args, "--signed=yes"); + strvec_push(&args, "--signed=yes"); else if (options.push_cert == SEND_PACK_PUSH_CERT_IF_ASKED) - argv_array_push(&args, "--signed=if-asked"); + strvec_push(&args, "--signed=if-asked"); if (options.atomic) - argv_array_push(&args, "--atomic"); + strvec_push(&args, "--atomic"); if (options.verbosity == 0) - argv_array_push(&args, "--quiet"); + strvec_push(&args, "--quiet"); else if (options.verbosity > 1) - argv_array_push(&args, "--verbose"); + strvec_push(&args, "--verbose"); for (i = 0; i < options.push_options.nr; i++) - argv_array_pushf(&args, "--push-option=%s", - options.push_options.items[i].string); - argv_array_push(&args, options.progress ? "--progress" : "--no-progress"); + strvec_pushf(&args, "--push-option=%s", + options.push_options.items[i].string); + strvec_push(&args, options.progress ? "--progress" : "--no-progress"); for_each_string_list_item(cas_option, &cas_options) - argv_array_push(&args, cas_option->string); - argv_array_push(&args, url.buf); + strvec_push(&args, cas_option->string); + strvec_push(&args, url.buf); - argv_array_push(&args, "--stdin"); + strvec_push(&args, "--stdin"); for (i = 0; i < nr_spec; i++) packet_buf_write(&preamble, "%s\n", specs[i]); packet_buf_flush(&preamble); @@ -1288,12 +1326,12 @@ static int push_git(struct discovery *heads, int nr_spec, const char **specs) memset(&rpc, 0, sizeof(rpc)); rpc.service_name = "git-receive-pack", - err = rpc_service(&rpc, heads, args.argv, &preamble, &rpc_result); + err = rpc_service(&rpc, heads, args.v, &preamble, &rpc_result); if (rpc_result.len) write_or_die(1, rpc_result.buf, rpc_result.len); strbuf_release(&rpc_result); strbuf_release(&preamble); - argv_array_clear(&args); + strvec_clear(&args); return err; } @@ -1312,13 +1350,13 @@ static int push(int nr_spec, const char **specs) static void parse_push(struct strbuf *buf) { - struct argv_array specs = ARGV_ARRAY_INIT; + struct strvec specs = STRVEC_INIT; int ret; do { const char *arg; if (skip_prefix(buf->buf, "push ", &arg)) - argv_array_push(&specs, arg); + strvec_push(&specs, arg); else die(_("http transport does not support %s"), buf->buf); @@ -1329,7 +1367,7 @@ static void parse_push(struct strbuf *buf) break; } while (1); - ret = push(specs.argc, specs.argv); + ret = push(specs.nr, specs.v); printf("\n"); fflush(stdout); @@ -1337,7 +1375,7 @@ static void parse_push(struct strbuf *buf) exit(128); /* error already reported */ free_specs: - argv_array_clear(&specs); + strvec_clear(&specs); } static int stateless_connect(const char *service_name) @@ -1499,6 +1537,7 @@ int cmd_main(int argc, const char **argv) printf("option\n"); printf("push\n"); printf("check-connectivity\n"); + printf("object-format\n"); printf("\n"); fflush(stdout); } else if (skip_prefix(buf.buf, "stateless-connect ", &arg)) { |