aboutsummaryrefslogtreecommitdiffstats
path: root/t/helper/test-path-walk.c
blob: 7f2d409c5bca6373e6c6331a9eee963c4c5ca893 (plain)
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;
}