aboutsummaryrefslogtreecommitdiffstats
path: root/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'transport.c')
-rw-r--r--transport.c52
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))