Skip to content

Commit 25ec7bc

Browse files
jeffhostetlergitster
authored andcommitted
list-objects: filter objects in traverse_commit_list
Create traverse_commit_list_filtered() and add filtering interface to allow certain objects to be omitted from the traversal. Update traverse_commit_list() to be a wrapper for the above with a null filter to minimize the number of callers that needed to be changed. Object filtering will be used in a future commit by rev-list and pack-objects for partial clone and fetch to omit unwanted objects from the result. traverse_bitmap_commit_list() does not work with filtering. If a packfile bitmap is present, it will not be used. It should be possible to extend such support in the future (at least to simple filters that do not require object pathnames), but that is beyond the scope of this patch series. Signed-off-by: Jeff Hostetler <[email protected]> Reviewed-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c3a9ad3 commit 25ec7bc

8 files changed

+711
-17
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,8 @@ LIB_OBJS += levenshtein.o
807807
LIB_OBJS += line-log.o
808808
LIB_OBJS += line-range.o
809809
LIB_OBJS += list-objects.o
810+
LIB_OBJS += list-objects-filter.o
811+
LIB_OBJS += list-objects-filter-options.o
810812
LIB_OBJS += ll-merge.o
811813
LIB_OBJS += lockfile.o
812814
LIB_OBJS += log-tree.o

list-objects-filter-options.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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" keword.
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+
*/
24+
int parse_list_objects_filter(struct list_objects_filter_options *filter_options,
25+
const char *arg)
26+
{
27+
const char *v0;
28+
29+
if (filter_options->choice)
30+
die(_("multiple object filter types cannot be combined"));
31+
32+
filter_options->filter_spec = strdup(arg);
33+
34+
if (!strcmp(arg, "blob:none")) {
35+
filter_options->choice = LOFC_BLOB_NONE;
36+
return 0;
37+
}
38+
39+
if (skip_prefix(arg, "blob:limit=", &v0)) {
40+
if (!git_parse_ulong(v0, &filter_options->blob_limit_value))
41+
die(_("invalid filter-spec expression '%s'"), arg);
42+
filter_options->choice = LOFC_BLOB_LIMIT;
43+
return 0;
44+
}
45+
46+
if (skip_prefix(arg, "sparse:oid=", &v0)) {
47+
struct object_context oc;
48+
struct object_id sparse_oid;
49+
50+
/*
51+
* Try to parse <oid-expression> into an OID for the current
52+
* command, but DO NOT complain if we don't have the blob or
53+
* ref locally.
54+
*/
55+
if (!get_oid_with_context(v0, GET_OID_BLOB,
56+
&sparse_oid, &oc))
57+
filter_options->sparse_oid_value = oiddup(&sparse_oid);
58+
filter_options->choice = LOFC_SPARSE_OID;
59+
return 0;
60+
}
61+
62+
if (skip_prefix(arg, "sparse:path=", &v0)) {
63+
filter_options->choice = LOFC_SPARSE_PATH;
64+
filter_options->sparse_path_value = strdup(v0);
65+
return 0;
66+
}
67+
68+
die(_("invalid filter-spec expression '%s'"), arg);
69+
return 0;
70+
}
71+
72+
int opt_parse_list_objects_filter(const struct option *opt,
73+
const char *arg, int unset)
74+
{
75+
struct list_objects_filter_options *filter_options = opt->value;
76+
77+
assert(arg);
78+
assert(!unset);
79+
80+
return parse_list_objects_filter(filter_options, arg);
81+
}

list-objects-filter-options.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#ifndef LIST_OBJECTS_FILTER_OPTIONS_H
2+
#define LIST_OBJECTS_FILTER_OPTIONS_H
3+
4+
#include "parse-options.h"
5+
6+
/*
7+
* The list of defined filters for list-objects.
8+
*/
9+
enum list_objects_filter_choice {
10+
LOFC_DISABLED = 0,
11+
LOFC_BLOB_NONE,
12+
LOFC_BLOB_LIMIT,
13+
LOFC_SPARSE_OID,
14+
LOFC_SPARSE_PATH,
15+
LOFC__COUNT /* must be last */
16+
};
17+
18+
struct list_objects_filter_options {
19+
/*
20+
* 'filter_spec' is the raw argument value given on the command line
21+
* or protocol request. (The part after the "--keyword=".) For
22+
* commands that launch filtering sub-processes, this value should be
23+
* passed to them as received by the current process.
24+
*/
25+
char *filter_spec;
26+
27+
/*
28+
* 'choice' is determined by parsing the filter-spec. This indicates
29+
* the filtering algorithm to use.
30+
*/
31+
enum list_objects_filter_choice choice;
32+
33+
/*
34+
* Parsed values (fields) from within the filter-spec. These are
35+
* choice-specific; not all values will be defined for any given
36+
* choice.
37+
*/
38+
struct object_id *sparse_oid_value;
39+
char *sparse_path_value;
40+
unsigned long blob_limit_value;
41+
};
42+
43+
/* Normalized command line arguments */
44+
#define CL_ARG__FILTER "filter"
45+
46+
int parse_list_objects_filter(
47+
struct list_objects_filter_options *filter_options,
48+
const char *arg);
49+
50+
int opt_parse_list_objects_filter(const struct option *opt,
51+
const char *arg, int unset);
52+
53+
#define OPT_PARSE_LIST_OBJECTS_FILTER(fo) \
54+
{ OPTION_CALLBACK, 0, CL_ARG__FILTER, fo, N_("args"), \
55+
N_("object filtering"), PARSE_OPT_NONEG, \
56+
opt_parse_list_objects_filter }
57+
58+
#endif /* LIST_OBJECTS_FILTER_OPTIONS_H */

0 commit comments

Comments
 (0)