| #define USE_THE_REPOSITORY_VARIABLE | |
| #include "test-tool.h" | |
| #include "dir.h" | |
| #include "environment.h" | |
| #include "hex.h" | |
| #include "list-objects-filter-options.h" | |
| #include "object-name.h" | |
| #include "object.h" | |
| #include "pretty.h" | |
| #include "revision.h" | |
| #include "setup.h" | |
| #include "parse-options.h" | |
| #include "strbuf.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, stdin_pl = 0, pl_sparse_trees = -1; | |
| struct rev_info revs = REV_INFO_INIT; | |
| struct path_walk_info info = PATH_WALK_INFO_INIT; | |
| struct path_walk_test_data data = { 0 }; | |
| struct list_objects_filter_options filter_options = | |
| LIST_OBJECTS_FILTER_INIT; | |
| 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_BOOL(0, "edge-aggressive", &info.edge_aggressive, | |
| N_("toggle aggressive edge walk")), | |
| OPT_BOOL(0, "stdin-pl", &stdin_pl, | |
| N_("read a pattern list over stdin")), | |
| OPT_BOOL(0, "pl-sparse-trees", &pl_sparse_trees, | |
| N_("toggle pruning of trees by sparse patterns")), | |
| OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options), | |
| OPT_END(), | |
| }; | |
| setup_git_directory(the_repository); | |
| repo_init_revisions(the_repository, &revs, NULL); | |
| 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]); | |
| /* Apply the filter after setup_revisions to avoid the --objects check. */ | |
| if (filter_options.choice) | |
| list_objects_filter_copy(&revs.filter, &filter_options); | |
| info.revs = &revs; | |
| info.path_fn = emit_block; | |
| info.path_fn_data = &data; | |
| if (stdin_pl) { | |
| struct strbuf in = STRBUF_INIT; | |
| CALLOC_ARRAY(info.pl, 1); | |
| info.pl_sparse_trees = (pl_sparse_trees >= 0) ? | |
| pl_sparse_trees : 1; | |
| info.pl->use_cone_patterns = 1; | |
| strbuf_fread(&in, 2048, stdin); | |
| add_patterns_from_buffer(in.buf, in.len, "", 0, info.pl); | |
| strbuf_release(&in); | |
| } | |
| 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); | |
| if (info.pl) { | |
| clear_pattern_list(info.pl); | |
| free(info.pl); | |
| } | |
| list_objects_filter_release(&filter_options); | |
| release_revisions(&revs); | |
| return res; | |
| } |