diff options
Diffstat (limited to 'transport.c')
| -rw-r--r-- | transport.c | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/transport.c b/transport.c index 3c4714581f..6966df51a8 100644 --- a/transport.c +++ b/transport.c @@ -19,6 +19,7 @@ #include "branch.h" #include "url.h" #include "submodule.h" +#include "strbuf.h" #include "string-list.h" #include "oid-array.h" #include "sigchain.h" @@ -172,12 +173,29 @@ static struct ref *get_refs_from_bundle(struct transport *transport, return result; } +static int fetch_fsck_config_cb(const char *var, const char *value, + const struct config_context *ctx UNUSED, void *cb) +{ + struct strbuf *msg_types = cb; + int ret; + + ret = fetch_pack_fsck_config(var, value, msg_types); + if (ret > 0) + return 0; + + return ret; +} + static int fetch_refs_from_bundle(struct transport *transport, int nr_heads UNUSED, struct ref **to_fetch UNUSED) { + struct unbundle_opts opts = { + .flags = fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0, + }; struct bundle_transport_data *data = transport->data; struct strvec extra_index_pack_args = STRVEC_INIT; + struct strbuf msg_types = STRBUF_INIT; int ret; if (transport->progress) @@ -185,12 +203,16 @@ static int fetch_refs_from_bundle(struct transport *transport, if (!data->get_refs_from_bundle_called) get_refs_from_bundle_inner(transport); + + git_config(fetch_fsck_config_cb, &msg_types); + opts.fsck_msg_types = msg_types.buf; + ret = unbundle(the_repository, &data->header, data->fd, - &extra_index_pack_args, - fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0); + &extra_index_pack_args, &opts); transport->hash_algo = data->header.hash_algo; strvec_clear(&extra_index_pack_args); + strbuf_release(&msg_types); return ret; } @@ -334,6 +356,9 @@ static struct ref *handshake(struct transport *transport, int for_push, data->version = discover_version(&reader); switch (data->version) { case protocol_v2: + if ((!transport->server_options || !transport->server_options->nr) && + transport->remote->server_options.nr) + transport->server_options = &transport->remote->server_options; if (server_feature_v2("session-id", &server_sid)) trace2_data_string("transfer", NULL, "server-sid", server_sid); if (must_list_refs) @@ -414,7 +439,7 @@ static int fetch_refs_via_pack(struct transport *transport, struct git_transport_data *data = transport->data; struct ref *refs = NULL; struct fetch_pack_args args; - struct ref *refs_tmp = NULL; + struct ref *refs_tmp = NULL, **to_fetch_dup = NULL; memset(&args, 0, sizeof(args)); args.uploadpack = data->options.uploadpack; @@ -477,6 +502,14 @@ static int fetch_refs_via_pack(struct transport *transport, goto cleanup; } + /* + * Create a shallow copy of `sought` so that we can free all of its entries. + * This is because `fetch_pack()` will modify the array to evict some + * entries, but won't free those. + */ + DUP_ARRAY(to_fetch_dup, to_fetch, nr_heads); + to_fetch = to_fetch_dup; + refs = fetch_pack(&args, data->fd, refs_tmp ? refs_tmp : transport->remote_refs, to_fetch, nr_heads, &data->shallow, @@ -500,6 +533,7 @@ cleanup: ret = -1; data->conn = NULL; + free(to_fetch_dup); free_refs(refs_tmp); free_refs(refs); list_objects_filter_release(&args.filter_options); @@ -1099,6 +1133,18 @@ int is_transport_allowed(const char *type, int from_user) BUG("invalid protocol_allow_config type"); } +int parse_transport_option(const char *var, const char *value, + struct string_list *transport_options) +{ + if (!value) + return config_error_nonbool(var); + if (!*value) + string_list_clear(transport_options, 0); + else + string_list_append(transport_options, value); + return 0; +} + void transport_check_allowed(const char *type) { if (!is_transport_allowed(type, -1)) |
