diff options
Diffstat (limited to 'upload-pack.c')
-rw-r--r-- | upload-pack.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/upload-pack.c b/upload-pack.c index 4c9428c2db..87b4d32a6e 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -9,6 +9,8 @@ #include "diff.h" #include "revision.h" #include "list-objects.h" +#include "list-objects-filter.h" +#include "list-objects-filter-options.h" #include "run-command.h" #include "connect.h" #include "sigchain.h" @@ -17,6 +19,7 @@ #include "argv-array.h" #include "prio-queue.h" #include "protocol.h" +#include "quote.h" #include "upload-pack.h" #include "serve.h" @@ -59,6 +62,10 @@ static int use_sideband; static int stateless_rpc; static const char *pack_objects_hook; +static int filter_capability_requested; +static int allow_filter; +static struct list_objects_filter_options filter_options; + static void reset_timeout(void) { alarm(timeout); @@ -126,6 +133,17 @@ static void create_pack_file(void) argv_array_push(&pack_objects.args, "--delta-base-offset"); if (use_include_tag) argv_array_push(&pack_objects.args, "--include-tag"); + if (filter_options.filter_spec) { + if (pack_objects.use_shell) { + struct strbuf buf = STRBUF_INIT; + sq_quote_buf(&buf, filter_options.filter_spec); + argv_array_pushf(&pack_objects.args, "--filter=%s", buf.buf); + strbuf_release(&buf); + } else { + argv_array_pushf(&pack_objects.args, "--filter=%s", + filter_options.filter_spec); + } + } pack_objects.in = -1; pack_objects.out = -1; @@ -869,6 +887,13 @@ static void receive_needs(void) if (process_deepen_not(line, &deepen_not, &deepen_rev_list)) continue; + if (skip_prefix(line, "filter ", &arg)) { + if (!filter_capability_requested) + die("git upload-pack: filtering capability not negotiated"); + parse_list_objects_filter(&filter_options, arg); + continue; + } + if (!skip_prefix(line, "want ", &arg) || get_oid_hex(arg, &oid_buf)) die("git upload-pack: protocol error, " @@ -896,6 +921,8 @@ static void receive_needs(void) no_progress = 1; if (parse_feature_request(features, "include-tag")) use_include_tag = 1; + if (allow_filter && parse_feature_request(features, "filter")) + filter_capability_requested = 1; o = parse_object(&oid_buf); if (!o) { @@ -985,7 +1012,7 @@ static int send_ref(const char *refname, const struct object_id *oid, struct strbuf symref_info = STRBUF_INIT; format_symref_info(&symref_info, cb_data); - packet_write_fmt(1, "%s %s%c%s%s%s%s%s agent=%s\n", + packet_write_fmt(1, "%s %s%c%s%s%s%s%s%s agent=%s\n", oid_to_hex(oid), refname_nons, 0, capabilities, (allow_unadvertised_object_request & ALLOW_TIP_SHA1) ? @@ -994,6 +1021,7 @@ static int send_ref(const char *refname, const struct object_id *oid, " allow-reachable-sha1-in-want" : "", stateless_rpc ? " no-done" : "", symref_info.buf, + allow_filter ? " filter" : "", git_user_agent_sanitized()); strbuf_release(&symref_info); } else { @@ -1045,6 +1073,8 @@ static int upload_pack_config(const char *var, const char *value, void *unused) } else if (current_config_scope() != CONFIG_SCOPE_REPO) { if (!strcmp("uploadpack.packobjectshook", var)) return git_config_string(&pack_objects_hook, var, value); + } else if (!strcmp("uploadpack.allowfilter", var)) { + allow_filter = git_config_bool(var, value); } return parse_hide_refs_config(var, value, "uploadpack"); } |