1#include"cache.h" 2#include"commit.h" 3#include"config.h" 4#include"revision.h" 5#include"argv-array.h" 6#include"list-objects.h" 7#include"list-objects-filter.h" 8#include"list-objects-filter-options.h" 9 10/* 11 * Parse value of the argument to the "filter" keyword. 12 * On the command line this looks like: 13 * --filter=<arg> 14 * and in the pack protocol as: 15 * "filter" SP <arg> 16 * 17 * The filter keyword will be used by many commands. 18 * See Documentation/rev-list-options.txt for allowed values for <arg>. 19 * 20 * Capture the given arg as the "filter_spec". This can be forwarded to 21 * subordinate commands when necessary. We also "intern" the arg for 22 * the convenience of the current command. 23 */ 24static intgently_parse_list_objects_filter( 25struct list_objects_filter_options *filter_options, 26const char*arg, 27struct strbuf *errbuf) 28{ 29const char*v0; 30 31if(filter_options->choice) { 32if(errbuf) { 33strbuf_addstr( 34 errbuf, 35_("multiple filter-specs cannot be combined")); 36} 37return1; 38} 39 40 filter_options->filter_spec =strdup(arg); 41 42if(!strcmp(arg,"blob:none")) { 43 filter_options->choice = LOFC_BLOB_NONE; 44return0; 45 46}else if(skip_prefix(arg,"blob:limit=", &v0)) { 47if(git_parse_ulong(v0, &filter_options->blob_limit_value)) { 48 filter_options->choice = LOFC_BLOB_LIMIT; 49return0; 50} 51 52}else if(skip_prefix(arg,"sparse:oid=", &v0)) { 53struct object_context oc; 54struct object_id sparse_oid; 55 56/* 57 * Try to parse <oid-expression> into an OID for the current 58 * command, but DO NOT complain if we don't have the blob or 59 * ref locally. 60 */ 61if(!get_oid_with_context(v0, GET_OID_BLOB, 62&sparse_oid, &oc)) 63 filter_options->sparse_oid_value =oiddup(&sparse_oid); 64 filter_options->choice = LOFC_SPARSE_OID; 65return0; 66 67}else if(skip_prefix(arg,"sparse:path=", &v0)) { 68 filter_options->choice = LOFC_SPARSE_PATH; 69 filter_options->sparse_path_value =strdup(v0); 70return0; 71} 72 73if(errbuf) 74strbuf_addf(errbuf,"invalid filter-spec '%s'", arg); 75 76memset(filter_options,0,sizeof(*filter_options)); 77return1; 78} 79 80intparse_list_objects_filter(struct list_objects_filter_options *filter_options, 81const char*arg) 82{ 83struct strbuf buf = STRBUF_INIT; 84if(gently_parse_list_objects_filter(filter_options, arg, &buf)) 85die("%s", buf.buf); 86return0; 87} 88 89intopt_parse_list_objects_filter(const struct option *opt, 90const char*arg,int unset) 91{ 92struct list_objects_filter_options *filter_options = opt->value; 93 94if(unset || !arg) { 95list_objects_filter_set_no_filter(filter_options); 96return0; 97} 98 99returnparse_list_objects_filter(filter_options, arg); 100} 101 102voidlist_objects_filter_release( 103struct list_objects_filter_options *filter_options) 104{ 105free(filter_options->filter_spec); 106free(filter_options->sparse_oid_value); 107free(filter_options->sparse_path_value); 108memset(filter_options,0,sizeof(*filter_options)); 109} 110 111voidpartial_clone_register( 112const char*remote, 113const struct list_objects_filter_options *filter_options) 114{ 115/* 116 * Record the name of the partial clone remote in the 117 * config and in the global variable -- the latter is 118 * used throughout to indicate that partial clone is 119 * enabled and to expect missing objects. 120 */ 121if(repository_format_partial_clone && 122*repository_format_partial_clone && 123strcmp(remote, repository_format_partial_clone)) 124die(_("cannot change partial clone promisor remote")); 125 126git_config_set("core.repositoryformatversion","1"); 127git_config_set("extensions.partialclone", remote); 128 129 repository_format_partial_clone =xstrdup(remote); 130 131/* 132 * Record the initial filter-spec in the config as 133 * the default for subsequent fetches from this remote. 134 */ 135 core_partial_clone_filter_default = 136xstrdup(filter_options->filter_spec); 137git_config_set("core.partialclonefilter", 138 core_partial_clone_filter_default); 139} 140 141voidpartial_clone_get_default_filter_spec( 142struct list_objects_filter_options *filter_options) 143{ 144/* 145 * Parse default value, but silently ignore it if it is invalid. 146 */ 147if(!core_partial_clone_filter_default) 148return; 149gently_parse_list_objects_filter(filter_options, 150 core_partial_clone_filter_default, 151 NULL); 152}