diff options
Diffstat (limited to 'third_party/git/list-objects-filter-options.c')
-rw-r--r-- | third_party/git/list-objects-filter-options.c | 402 |
1 files changed, 0 insertions, 402 deletions
diff --git a/third_party/git/list-objects-filter-options.c b/third_party/git/list-objects-filter-options.c deleted file mode 100644 index defd3dfd10..0000000000 --- a/third_party/git/list-objects-filter-options.c +++ /dev/null @@ -1,402 +0,0 @@ -#include "cache.h" -#include "commit.h" -#include "config.h" -#include "revision.h" -#include "strvec.h" -#include "list-objects.h" -#include "list-objects-filter.h" -#include "list-objects-filter-options.h" -#include "promisor-remote.h" -#include "trace.h" -#include "url.h" - -static int parse_combine_filter( - struct list_objects_filter_options *filter_options, - const char *arg, - struct strbuf *errbuf); - -const char *list_object_filter_config_name(enum list_objects_filter_choice c) -{ - switch (c) { - case LOFC_DISABLED: - /* we have no name for "no filter at all" */ - break; - case LOFC_BLOB_NONE: - return "blob:none"; - case LOFC_BLOB_LIMIT: - return "blob:limit"; - case LOFC_TREE_DEPTH: - return "tree"; - case LOFC_SPARSE_OID: - return "sparse:oid"; - case LOFC_COMBINE: - return "combine"; - case LOFC__COUNT: - /* not a real filter type; just the count of all filters */ - break; - } - BUG("list_object_filter_choice_name: invalid argument '%d'", c); -} - -/* - * Parse value of the argument to the "filter" keyword. - * On the command line this looks like: - * --filter=<arg> - * and in the pack protocol as: - * "filter" SP <arg> - * - * The filter keyword will be used by many commands. - * See Documentation/rev-list-options.txt for allowed values for <arg>. - * - * Capture the given arg as the "filter_spec". This can be forwarded to - * subordinate commands when necessary (although it's better to pass it through - * expand_list_objects_filter_spec() first). We also "intern" the arg for the - * convenience of the current command. - */ -static int gently_parse_list_objects_filter( - struct list_objects_filter_options *filter_options, - const char *arg, - struct strbuf *errbuf) -{ - const char *v0; - - if (!arg) - return 0; - - if (filter_options->choice) - BUG("filter_options already populated"); - - if (!strcmp(arg, "blob:none")) { - filter_options->choice = LOFC_BLOB_NONE; - return 0; - - } else if (skip_prefix(arg, "blob:limit=", &v0)) { - if (git_parse_ulong(v0, &filter_options->blob_limit_value)) { - filter_options->choice = LOFC_BLOB_LIMIT; - return 0; - } - - } else if (skip_prefix(arg, "tree:", &v0)) { - if (!git_parse_ulong(v0, &filter_options->tree_exclude_depth)) { - strbuf_addstr(errbuf, _("expected 'tree:<depth>'")); - return 1; - } - filter_options->choice = LOFC_TREE_DEPTH; - return 0; - - } else if (skip_prefix(arg, "sparse:oid=", &v0)) { - filter_options->sparse_oid_name = xstrdup(v0); - filter_options->choice = LOFC_SPARSE_OID; - return 0; - - } else if (skip_prefix(arg, "sparse:path=", &v0)) { - if (errbuf) { - strbuf_addstr( - errbuf, - _("sparse:path filters support has been dropped")); - } - return 1; - - } else if (skip_prefix(arg, "combine:", &v0)) { - return parse_combine_filter(filter_options, v0, errbuf); - - } - /* - * Please update _git_fetch() in git-completion.bash when you - * add new filters - */ - - strbuf_addf(errbuf, _("invalid filter-spec '%s'"), arg); - - memset(filter_options, 0, sizeof(*filter_options)); - return 1; -} - -static const char *RESERVED_NON_WS = "~`!@#$^&*()[]{}\\;'\",<>?"; - -static int has_reserved_character( - struct strbuf *sub_spec, struct strbuf *errbuf) -{ - const char *c = sub_spec->buf; - while (*c) { - if (*c <= ' ' || strchr(RESERVED_NON_WS, *c)) { - strbuf_addf( - errbuf, - _("must escape char in sub-filter-spec: '%c'"), - *c); - return 1; - } - c++; - } - - return 0; -} - -static int parse_combine_subfilter( - struct list_objects_filter_options *filter_options, - struct strbuf *subspec, - struct strbuf *errbuf) -{ - size_t new_index = filter_options->sub_nr; - char *decoded; - int result; - - ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1, - filter_options->sub_alloc); - - decoded = url_percent_decode(subspec->buf); - - result = has_reserved_character(subspec, errbuf) || - gently_parse_list_objects_filter( - &filter_options->sub[new_index], decoded, errbuf); - - free(decoded); - return result; -} - -static int parse_combine_filter( - struct list_objects_filter_options *filter_options, - const char *arg, - struct strbuf *errbuf) -{ - struct strbuf **subspecs = strbuf_split_str(arg, '+', 0); - size_t sub; - int result = 0; - - if (!subspecs[0]) { - strbuf_addstr(errbuf, _("expected something after combine:")); - result = 1; - goto cleanup; - } - - for (sub = 0; subspecs[sub] && !result; sub++) { - if (subspecs[sub + 1]) { - /* - * This is not the last subspec. Remove trailing "+" so - * we can parse it. - */ - size_t last = subspecs[sub]->len - 1; - assert(subspecs[sub]->buf[last] == '+'); - strbuf_remove(subspecs[sub], last, 1); - } - result = parse_combine_subfilter( - filter_options, subspecs[sub], errbuf); - } - - filter_options->choice = LOFC_COMBINE; - -cleanup: - strbuf_list_free(subspecs); - if (result) { - list_objects_filter_release(filter_options); - memset(filter_options, 0, sizeof(*filter_options)); - } - return result; -} - -static int allow_unencoded(char ch) -{ - if (ch <= ' ' || ch == '%' || ch == '+') - return 0; - return !strchr(RESERVED_NON_WS, ch); -} - -static void filter_spec_append_urlencode( - struct list_objects_filter_options *filter, const char *raw) -{ - struct strbuf buf = STRBUF_INIT; - strbuf_addstr_urlencode(&buf, raw, allow_unencoded); - trace_printf("Add to combine filter-spec: %s\n", buf.buf); - string_list_append(&filter->filter_spec, strbuf_detach(&buf, NULL)); -} - -/* - * Changes filter_options into an equivalent LOFC_COMBINE filter options - * instance. Does not do anything if filter_options is already LOFC_COMBINE. - */ -static void transform_to_combine_type( - struct list_objects_filter_options *filter_options) -{ - assert(filter_options->choice); - if (filter_options->choice == LOFC_COMBINE) - return; - { - const int initial_sub_alloc = 2; - struct list_objects_filter_options *sub_array = - xcalloc(initial_sub_alloc, sizeof(*sub_array)); - sub_array[0] = *filter_options; - memset(filter_options, 0, sizeof(*filter_options)); - filter_options->sub = sub_array; - filter_options->sub_alloc = initial_sub_alloc; - } - filter_options->sub_nr = 1; - filter_options->choice = LOFC_COMBINE; - string_list_append(&filter_options->filter_spec, xstrdup("combine:")); - filter_spec_append_urlencode( - filter_options, - list_objects_filter_spec(&filter_options->sub[0])); - /* - * We don't need the filter_spec strings for subfilter specs, only the - * top level. - */ - string_list_clear(&filter_options->sub[0].filter_spec, /*free_util=*/0); -} - -void list_objects_filter_die_if_populated( - struct list_objects_filter_options *filter_options) -{ - if (filter_options->choice) - die(_("multiple filter-specs cannot be combined")); -} - -void parse_list_objects_filter( - struct list_objects_filter_options *filter_options, - const char *arg) -{ - struct strbuf errbuf = STRBUF_INIT; - int parse_error; - - if (!filter_options->choice) { - string_list_append(&filter_options->filter_spec, xstrdup(arg)); - - parse_error = gently_parse_list_objects_filter( - filter_options, arg, &errbuf); - } else { - /* - * Make filter_options an LOFC_COMBINE spec so we can trivially - * add subspecs to it. - */ - transform_to_combine_type(filter_options); - - string_list_append(&filter_options->filter_spec, xstrdup("+")); - filter_spec_append_urlencode(filter_options, arg); - ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1, - filter_options->sub_alloc); - - parse_error = gently_parse_list_objects_filter( - &filter_options->sub[filter_options->sub_nr - 1], arg, - &errbuf); - } - if (parse_error) - die("%s", errbuf.buf); -} - -int opt_parse_list_objects_filter(const struct option *opt, - const char *arg, int unset) -{ - struct list_objects_filter_options *filter_options = opt->value; - - if (unset || !arg) - list_objects_filter_set_no_filter(filter_options); - else - parse_list_objects_filter(filter_options, arg); - return 0; -} - -const char *list_objects_filter_spec(struct list_objects_filter_options *filter) -{ - if (!filter->filter_spec.nr) - BUG("no filter_spec available for this filter"); - if (filter->filter_spec.nr != 1) { - struct strbuf concatted = STRBUF_INIT; - strbuf_add_separated_string_list( - &concatted, "", &filter->filter_spec); - string_list_clear(&filter->filter_spec, /*free_util=*/0); - string_list_append( - &filter->filter_spec, strbuf_detach(&concatted, NULL)); - } - - return filter->filter_spec.items[0].string; -} - -const char *expand_list_objects_filter_spec( - struct list_objects_filter_options *filter) -{ - if (filter->choice == LOFC_BLOB_LIMIT) { - struct strbuf expanded_spec = STRBUF_INIT; - strbuf_addf(&expanded_spec, "blob:limit=%lu", - filter->blob_limit_value); - string_list_clear(&filter->filter_spec, /*free_util=*/0); - string_list_append( - &filter->filter_spec, - strbuf_detach(&expanded_spec, NULL)); - } - - return list_objects_filter_spec(filter); -} - -void list_objects_filter_release( - struct list_objects_filter_options *filter_options) -{ - size_t sub; - - if (!filter_options) - return; - string_list_clear(&filter_options->filter_spec, /*free_util=*/0); - free(filter_options->sparse_oid_name); - for (sub = 0; sub < filter_options->sub_nr; sub++) - list_objects_filter_release(&filter_options->sub[sub]); - free(filter_options->sub); - memset(filter_options, 0, sizeof(*filter_options)); -} - -void partial_clone_register( - const char *remote, - struct list_objects_filter_options *filter_options) -{ - struct promisor_remote *promisor_remote; - char *cfg_name; - char *filter_name; - - /* Check if it is already registered */ - if ((promisor_remote = promisor_remote_find(remote))) { - if (promisor_remote->partial_clone_filter) - /* - * Remote is already registered and a filter is already - * set, so we don't need to do anything here. - */ - return; - } else { - if (upgrade_repository_format(1) < 0) - die(_("unable to upgrade repository format to support partial clone")); - - /* Add promisor config for the remote */ - cfg_name = xstrfmt("remote.%s.promisor", remote); - git_config_set(cfg_name, "true"); - free(cfg_name); - } - - /* - * Record the initial filter-spec in the config as - * the default for subsequent fetches from this remote. - */ - filter_name = xstrfmt("remote.%s.partialclonefilter", remote); - /* NEEDSWORK: 'expand' result leaking??? */ - git_config_set(filter_name, - expand_list_objects_filter_spec(filter_options)); - free(filter_name); - - /* Make sure the config info are reset */ - promisor_remote_reinit(); -} - -void partial_clone_get_default_filter_spec( - struct list_objects_filter_options *filter_options, - const char *remote) -{ - struct promisor_remote *promisor = promisor_remote_find(remote); - struct strbuf errbuf = STRBUF_INIT; - - /* - * Parse default value, but silently ignore it if it is invalid. - */ - if (!promisor) - return; - - string_list_append(&filter_options->filter_spec, - promisor->partial_clone_filter); - gently_parse_list_objects_filter(filter_options, - promisor->partial_clone_filter, - &errbuf); - strbuf_release(&errbuf); -} |