Raw
1 #define USE_THE_REPOSITORY_VARIABLE
2
3 #include "test-tool.h"
4 #include "dir.h"
5 #include "environment.h"
6 #include "hex.h"
7 #include "list-objects-filter-options.h"
8 #include "object-name.h"
9 #include "object.h"
10 #include "pretty.h"
11 #include "revision.h"
12 #include "setup.h"
13 #include "parse-options.h"
14 #include "strbuf.h"
15 #include "path-walk.h"
16 #include "oid-array.h"
17
18 static const char * const path_walk_usage[] = {
19 N_("test-tool path-walk <options> -- <revision-options>"),
20 NULL
21 };
22
23 struct path_walk_test_data {
24 uintmax_t batch_nr;
25
26 uintmax_t commit_nr;
27 uintmax_t tree_nr;
28 uintmax_t blob_nr;
29 uintmax_t tag_nr;
30 };
31
32 static int emit_block(const char *path, struct oid_array *oids,
33 enum object_type type, void *data)
34 {
35 struct path_walk_test_data *tdata = data;
36 const char *typestr;
37
38 if (type == OBJ_TREE)
39 tdata->tree_nr += oids->nr;
40 else if (type == OBJ_BLOB)
41 tdata->blob_nr += oids->nr;
42 else if (type == OBJ_COMMIT)
43 tdata->commit_nr += oids->nr;
44 else if (type == OBJ_TAG)
45 tdata->tag_nr += oids->nr;
46 else
47 BUG("we do not understand this type");
48
49 typestr = type_name(type);
50
51 /* This should never be output during tests. */
52 if (!oids->nr)
53 printf("%"PRIuMAX":%s:%s:EMPTY\n",
54 tdata->batch_nr, typestr, path);
55
56 for (size_t i = 0; i < oids->nr; i++) {
57 struct object *o = lookup_unknown_object(the_repository,
58 &oids->oid[i]);
59 printf("%"PRIuMAX":%s:%s:%s%s\n",
60 tdata->batch_nr, typestr, path,
61 oid_to_hex(&oids->oid[i]),
62 o->flags & UNINTERESTING ? ":UNINTERESTING" : "");
63 }
64
65 tdata->batch_nr++;
66 return 0;
67 }
68
69 int cmd__path_walk(int argc, const char **argv)
70 {
71 int res, stdin_pl = 0, pl_sparse_trees = -1;
72 struct rev_info revs = REV_INFO_INIT;
73 struct path_walk_info info = PATH_WALK_INFO_INIT;
74 struct path_walk_test_data data = { 0 };
75 struct list_objects_filter_options filter_options =
76 LIST_OBJECTS_FILTER_INIT;
77 struct option options[] = {
78 OPT_BOOL(0, "blobs", &info.blobs,
79 N_("toggle inclusion of blob objects")),
80 OPT_BOOL(0, "commits", &info.commits,
81 N_("toggle inclusion of commit objects")),
82 OPT_BOOL(0, "tags", &info.tags,
83 N_("toggle inclusion of tag objects")),
84 OPT_BOOL(0, "trees", &info.trees,
85 N_("toggle inclusion of tree objects")),
86 OPT_BOOL(0, "prune", &info.prune_all_uninteresting,
87 N_("toggle pruning of uninteresting paths")),
88 OPT_BOOL(0, "edge-aggressive", &info.edge_aggressive,
89 N_("toggle aggressive edge walk")),
90 OPT_BOOL(0, "stdin-pl", &stdin_pl,
91 N_("read a pattern list over stdin")),
92 OPT_BOOL(0, "pl-sparse-trees", &pl_sparse_trees,
93 N_("toggle pruning of trees by sparse patterns")),
94 OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
95 OPT_END(),
96 };
97
98 setup_git_directory(the_repository);
99 repo_init_revisions(the_repository, &revs, NULL);
100
101 argc = parse_options(argc, argv, NULL,
102 options, path_walk_usage,
103 PARSE_OPT_KEEP_UNKNOWN_OPT | PARSE_OPT_KEEP_ARGV0);
104
105 if (argc > 1)
106 setup_revisions(argc, argv, &revs, NULL);
107 else
108 usage(path_walk_usage[0]);
109
110 /* Apply the filter after setup_revisions to avoid the --objects check. */
111 if (filter_options.choice)
112 list_objects_filter_copy(&revs.filter, &filter_options);
113
114 info.revs = &revs;
115 info.path_fn = emit_block;
116 info.path_fn_data = &data;
117
118 if (stdin_pl) {
119 struct strbuf in = STRBUF_INIT;
120 CALLOC_ARRAY(info.pl, 1);
121 info.pl_sparse_trees = (pl_sparse_trees >= 0) ?
122 pl_sparse_trees : 1;
123
124 info.pl->use_cone_patterns = 1;
125
126 strbuf_fread(&in, 2048, stdin);
127 add_patterns_from_buffer(in.buf, in.len, "", 0, info.pl);
128 strbuf_release(&in);
129 }
130
131 res = walk_objects_by_path(&info);
132
133 printf("commits:%" PRIuMAX "\n"
134 "trees:%" PRIuMAX "\n"
135 "blobs:%" PRIuMAX "\n"
136 "tags:%" PRIuMAX "\n",
137 data.commit_nr, data.tree_nr, data.blob_nr, data.tag_nr);
138
139 if (info.pl) {
140 clear_pattern_list(info.pl);
141 free(info.pl);
142 }
143
144 list_objects_filter_release(&filter_options);
145 release_revisions(&revs);
146 return res;
147 }