1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#define USE_THE_REPOSITORY_VARIABLE
#include "test-tool.h"
#include "environment.h"
#include "hex.h"
#include "object-name.h"
#include "object.h"
#include "pretty.h"
#include "revision.h"
#include "setup.h"
#include "parse-options.h"
#include "path-walk.h"
#include "oid-array.h"
static const char * const path_walk_usage[] = {
N_("test-tool path-walk <options> -- <revision-options>"),
NULL
};
struct path_walk_test_data {
uintmax_t batch_nr;
uintmax_t commit_nr;
uintmax_t tree_nr;
uintmax_t blob_nr;
uintmax_t tag_nr;
};
static int emit_block(const char *path, struct oid_array *oids,
enum object_type type, void *data)
{
struct path_walk_test_data *tdata = data;
const char *typestr;
if (type == OBJ_TREE)
tdata->tree_nr += oids->nr;
else if (type == OBJ_BLOB)
tdata->blob_nr += oids->nr;
else if (type == OBJ_COMMIT)
tdata->commit_nr += oids->nr;
else if (type == OBJ_TAG)
tdata->tag_nr += oids->nr;
else
BUG("we do not understand this type");
typestr = type_name(type);
/* This should never be output during tests. */
if (!oids->nr)
printf("%"PRIuMAX":%s:%s:EMPTY\n",
tdata->batch_nr, typestr, path);
for (size_t i = 0; i < oids->nr; i++) {
struct object *o = lookup_unknown_object(the_repository,
&oids->oid[i]);
printf("%"PRIuMAX":%s:%s:%s%s\n",
tdata->batch_nr, typestr, path,
oid_to_hex(&oids->oid[i]),
o->flags & UNINTERESTING ? ":UNINTERESTING" : "");
}
tdata->batch_nr++;
return 0;
}
int cmd__path_walk(int argc, const char **argv)
{
int res;
struct rev_info revs = REV_INFO_INIT;
struct path_walk_info info = PATH_WALK_INFO_INIT;
struct path_walk_test_data data = { 0 };
struct option options[] = {
OPT_BOOL(0, "blobs", &info.blobs,
N_("toggle inclusion of blob objects")),
OPT_BOOL(0, "commits", &info.commits,
N_("toggle inclusion of commit objects")),
OPT_BOOL(0, "tags", &info.tags,
N_("toggle inclusion of tag objects")),
OPT_BOOL(0, "trees", &info.trees,
N_("toggle inclusion of tree objects")),
OPT_BOOL(0, "prune", &info.prune_all_uninteresting,
N_("toggle pruning of uninteresting paths")),
OPT_END(),
};
setup_git_directory();
revs.repo = the_repository;
argc = parse_options(argc, argv, NULL,
options, path_walk_usage,
PARSE_OPT_KEEP_UNKNOWN_OPT | PARSE_OPT_KEEP_ARGV0);
if (argc > 1)
setup_revisions(argc, argv, &revs, NULL);
else
usage(path_walk_usage[0]);
info.revs = &revs;
info.path_fn = emit_block;
info.path_fn_data = &data;
res = walk_objects_by_path(&info);
printf("commits:%" PRIuMAX "\n"
"trees:%" PRIuMAX "\n"
"blobs:%" PRIuMAX "\n"
"tags:%" PRIuMAX "\n",
data.commit_nr, data.tree_nr, data.blob_nr, data.tag_nr);
release_revisions(&revs);
return res;
}
|