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_init(errbuf,0); 34strbuf_addstr( 35 errbuf, 36_("multiple filter-specs cannot be combined")); 37} 38return1; 39} 40 41 filter_options->filter_spec =strdup(arg); 42 43if(!strcmp(arg,"blob:none")) { 44 filter_options->choice = LOFC_BLOB_NONE; 45return0; 46 47}else if(skip_prefix(arg,"blob:limit=", &v0)) { 48if(git_parse_ulong(v0, &filter_options->blob_limit_value)) { 49 filter_options->choice = LOFC_BLOB_LIMIT; 50return0; 51} 52 53}else if(skip_prefix(arg,"sparse:oid=", &v0)) { 54struct object_context oc; 55struct object_id sparse_oid; 56 57/* 58 * Try to parse <oid-expression> into an OID for the current 59 * command, but DO NOT complain if we don't have the blob or 60 * ref locally. 61 */ 62if(!get_oid_with_context(v0, GET_OID_BLOB, 63&sparse_oid, &oc)) 64 filter_options->sparse_oid_value =oiddup(&sparse_oid); 65 filter_options->choice = LOFC_SPARSE_OID; 66return0; 67 68}else if(skip_prefix(arg,"sparse:path=", &v0)) { 69 filter_options->choice = LOFC_SPARSE_PATH; 70 filter_options->sparse_path_value =strdup(v0); 71return0; 72} 73 74if(errbuf) { 75strbuf_init(errbuf,0); 76strbuf_addf(errbuf,"invalid filter-spec '%s'", arg); 77} 78memset(filter_options,0,sizeof(*filter_options)); 79return1; 80} 81 82intparse_list_objects_filter(struct list_objects_filter_options *filter_options, 83const char*arg) 84{ 85struct strbuf buf = STRBUF_INIT; 86if(gently_parse_list_objects_filter(filter_options, arg, &buf)) 87die("%s", buf.buf); 88return0; 89} 90 91intopt_parse_list_objects_filter(const struct option *opt, 92const char*arg,int unset) 93{ 94struct list_objects_filter_options *filter_options = opt->value; 95 96if(unset || !arg) { 97list_objects_filter_set_no_filter(filter_options); 98return0; 99} 100 101returnparse_list_objects_filter(filter_options, arg); 102} 103 104voidlist_objects_filter_release( 105struct list_objects_filter_options *filter_options) 106{ 107free(filter_options->filter_spec); 108free(filter_options->sparse_oid_value); 109free(filter_options->sparse_path_value); 110memset(filter_options,0,sizeof(*filter_options)); 111} 112 113voidpartial_clone_register( 114const char*remote, 115const struct list_objects_filter_options *filter_options) 116{ 117/* 118 * Record the name of the partial clone remote in the 119 * config and in the global variable -- the latter is 120 * used throughout to indicate that partial clone is 121 * enabled and to expect missing objects. 122 */ 123if(repository_format_partial_clone && 124*repository_format_partial_clone && 125strcmp(remote, repository_format_partial_clone)) 126die(_("cannot change partial clone promisor remote")); 127 128git_config_set("core.repositoryformatversion","1"); 129git_config_set("extensions.partialclone", remote); 130 131 repository_format_partial_clone =xstrdup(remote); 132 133/* 134 * Record the initial filter-spec in the config as 135 * the default for subsequent fetches from this remote. 136 */ 137 core_partial_clone_filter_default = 138xstrdup(filter_options->filter_spec); 139git_config_set("core.partialclonefilter", 140 core_partial_clone_filter_default); 141} 142 143voidpartial_clone_get_default_filter_spec( 144struct list_objects_filter_options *filter_options) 145{ 146/* 147 * Parse default value, but silently ignore it if it is invalid. 148 */ 149if(!core_partial_clone_filter_default) 150return; 151gently_parse_list_objects_filter(filter_options, 152 core_partial_clone_filter_default, 153 NULL); 154}