From 5faf357b4314fcc7976f75c7f3ba205d9eba8e77 Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Wed, 11 Jul 2018 15:42:37 -0700 Subject: [PATCH 1/6] commit-graph: refactor preparing commit graph Two functions in the code (1) check if the repository is configured for commit graphs, (2) call prepare_commit_graph(), and (3) check if the graph exists. Move (1) and (3) into prepare_commit_graph(), reducing duplication of code. Signed-off-by: Jonathan Tan Signed-off-by: Junio C Hamano --- commit-graph.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/commit-graph.c b/commit-graph.c index 41a0133ff75061..1ea701ed698553 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -200,15 +200,25 @@ static void prepare_commit_graph_one(const char *obj_dir) } static int prepare_commit_graph_run_once = 0; -static void prepare_commit_graph(void) + +/* + * Return 1 if commit_graph is non-NULL, and 0 otherwise. + * + * On the first invocation, this function attemps to load the commit + * graph if the_repository is configured to have one. + */ +static int prepare_commit_graph(void) { struct alternate_object_database *alt; char *obj_dir; if (prepare_commit_graph_run_once) - return; + return !!commit_graph; prepare_commit_graph_run_once = 1; + if (!core_commit_graph) + return 0; + obj_dir = get_object_directory(); prepare_commit_graph_one(obj_dir); prepare_alt_odb(the_repository); @@ -216,6 +226,7 @@ static void prepare_commit_graph(void) !commit_graph && alt; alt = alt->next) prepare_commit_graph_one(alt->path); + return !!commit_graph; } static void close_commit_graph(void) @@ -337,22 +348,17 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item int parse_commit_in_graph(struct commit *item) { - if (!core_commit_graph) + if (!prepare_commit_graph()) return 0; - - prepare_commit_graph(); - if (commit_graph) - return parse_commit_in_graph_one(commit_graph, item); - return 0; + return parse_commit_in_graph_one(commit_graph, item); } void load_commit_graph_info(struct commit *item) { uint32_t pos; - if (!core_commit_graph) + if (!prepare_commit_graph()) return; - prepare_commit_graph(); - if (commit_graph && find_commit_in_graph(item, commit_graph, &pos)) + if (find_commit_in_graph(item, commit_graph, &pos)) fill_commit_graph_info(item, commit_graph, pos); } From 14727b7fe6e8347f49689aba493b91bd6aecfc8d Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Wed, 11 Jul 2018 15:42:38 -0700 Subject: [PATCH 2/6] object-store: add missing include Signed-off-by: Jonathan Tan Signed-off-by: Junio C Hamano --- object-store.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/object-store.h b/object-store.h index a3db17bbf5a70c..0e13543babf4f8 100644 --- a/object-store.h +++ b/object-store.h @@ -2,6 +2,9 @@ #define OBJECT_STORE_H #include "oidmap.h" +#include "list.h" +#include "sha1-array.h" +#include "strbuf.h" struct alternate_object_database { struct alternate_object_database *next; From e5c5ca27292d302b7ccf7e44c43d8b9474513867 Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Wed, 11 Jul 2018 15:42:39 -0700 Subject: [PATCH 3/6] commit-graph: add missing forward declaration Signed-off-by: Jonathan Tan Signed-off-by: Junio C Hamano --- commit-graph.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/commit-graph.h b/commit-graph.h index 506cb45fb11782..674052bef49c08 100644 --- a/commit-graph.h +++ b/commit-graph.h @@ -5,6 +5,8 @@ #include "repository.h" #include "string-list.h" +struct commit; + char *get_commit_graph_filename(const char *obj_dir); /* From c3756d5b7fc6e163032296aa6c10fad2589273dc Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Wed, 11 Jul 2018 15:42:40 -0700 Subject: [PATCH 4/6] commit-graph: add free_commit_graph Signed-off-by: Jonathan Tan Signed-off-by: Junio C Hamano --- builtin/commit-graph.c | 2 ++ commit-graph.c | 24 ++++++++++++++---------- commit-graph.h | 2 ++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index c7d0db5ab4b668..0bf0c486575a85 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -115,6 +115,8 @@ static int graph_read(int argc, const char **argv) printf(" large_edges"); printf("\n"); + free_commit_graph(graph); + return 0; } diff --git a/commit-graph.c b/commit-graph.c index 1ea701ed698553..143a587581c267 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -231,16 +231,8 @@ static int prepare_commit_graph(void) static void close_commit_graph(void) { - if (!commit_graph) - return; - - if (commit_graph->graph_fd >= 0) { - munmap((void *)commit_graph->data, commit_graph->data_len); - commit_graph->data = NULL; - close(commit_graph->graph_fd); - } - - FREE_AND_NULL(commit_graph); + free_commit_graph(commit_graph); + commit_graph = NULL; } static int bsearch_graph(struct commit_graph *g, struct object_id *oid, uint32_t *pos) @@ -1033,3 +1025,15 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g) return verify_commit_graph_error; } + +void free_commit_graph(struct commit_graph *g) +{ + if (!g) + return; + if (g->graph_fd >= 0) { + munmap((void *)g->data, g->data_len); + g->data = NULL; + close(g->graph_fd); + } + free(g); +} diff --git a/commit-graph.h b/commit-graph.h index 674052bef49c08..94defb04a92478 100644 --- a/commit-graph.h +++ b/commit-graph.h @@ -58,4 +58,6 @@ void write_commit_graph(const char *obj_dir, int verify_commit_graph(struct repository *r, struct commit_graph *g); +void free_commit_graph(struct commit_graph *); + #endif From 8527750626f8a1b0fe641a5163760be054cc1d64 Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Wed, 11 Jul 2018 15:42:41 -0700 Subject: [PATCH 5/6] commit-graph: store graph in struct object_store Instead of storing commit graphs in static variables, store them in struct object_store. There are no changes to the signatures of existing functions - they all still only support the_repository, and support for other instances of struct repository will be added in a subsequent commit. Signed-off-by: Jonathan Tan Signed-off-by: Junio C Hamano --- commit-graph.c | 40 +++++++++++++++++++--------------------- object-store.h | 3 +++ object.c | 5 +++++ 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/commit-graph.c b/commit-graph.c index 143a587581c267..b6a76a1413f620 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -183,24 +183,20 @@ struct commit_graph *load_commit_graph_one(const char *graph_file) exit(1); } -/* global storage */ -static struct commit_graph *commit_graph = NULL; - static void prepare_commit_graph_one(const char *obj_dir) { char *graph_name; - if (commit_graph) + if (the_repository->objects->commit_graph) return; graph_name = get_commit_graph_filename(obj_dir); - commit_graph = load_commit_graph_one(graph_name); + the_repository->objects->commit_graph = + load_commit_graph_one(graph_name); FREE_AND_NULL(graph_name); } -static int prepare_commit_graph_run_once = 0; - /* * Return 1 if commit_graph is non-NULL, and 0 otherwise. * @@ -212,9 +208,9 @@ static int prepare_commit_graph(void) struct alternate_object_database *alt; char *obj_dir; - if (prepare_commit_graph_run_once) - return !!commit_graph; - prepare_commit_graph_run_once = 1; + if (the_repository->objects->commit_graph_attempted) + return !!the_repository->objects->commit_graph; + the_repository->objects->commit_graph_attempted = 1; if (!core_commit_graph) return 0; @@ -223,16 +219,16 @@ static int prepare_commit_graph(void) prepare_commit_graph_one(obj_dir); prepare_alt_odb(the_repository); for (alt = the_repository->objects->alt_odb_list; - !commit_graph && alt; + !the_repository->objects->commit_graph && alt; alt = alt->next) prepare_commit_graph_one(alt->path); - return !!commit_graph; + return !!the_repository->objects->commit_graph; } static void close_commit_graph(void) { - free_commit_graph(commit_graph); - commit_graph = NULL; + free_commit_graph(the_repository->objects->commit_graph); + the_repository->objects->commit_graph = NULL; } static int bsearch_graph(struct commit_graph *g, struct object_id *oid, uint32_t *pos) @@ -342,7 +338,7 @@ int parse_commit_in_graph(struct commit *item) { if (!prepare_commit_graph()) return 0; - return parse_commit_in_graph_one(commit_graph, item); + return parse_commit_in_graph_one(the_repository->objects->commit_graph, item); } void load_commit_graph_info(struct commit *item) @@ -350,8 +346,8 @@ void load_commit_graph_info(struct commit *item) uint32_t pos; if (!prepare_commit_graph()) return; - if (find_commit_in_graph(item, commit_graph, &pos)) - fill_commit_graph_info(item, commit_graph, pos); + if (find_commit_in_graph(item, the_repository->objects->commit_graph, &pos)) + fill_commit_graph_info(item, the_repository->objects->commit_graph, pos); } static struct tree *load_tree_for_commit(struct commit_graph *g, struct commit *c) @@ -379,7 +375,7 @@ static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g, struct tree *get_commit_tree_in_graph(const struct commit *c) { - return get_commit_tree_in_graph_one(commit_graph, c); + return get_commit_tree_in_graph_one(the_repository->objects->commit_graph, c); } static void write_graph_chunk_fanout(struct hashfile *f, @@ -696,15 +692,17 @@ void write_commit_graph(const char *obj_dir, if (append) { prepare_commit_graph_one(obj_dir); - if (commit_graph) - oids.alloc += commit_graph->num_commits; + if (the_repository->objects->commit_graph) + oids.alloc += the_repository->objects->commit_graph->num_commits; } if (oids.alloc < 1024) oids.alloc = 1024; ALLOC_ARRAY(oids.list, oids.alloc); - if (append && commit_graph) { + if (append && the_repository->objects->commit_graph) { + struct commit_graph *commit_graph = + the_repository->objects->commit_graph; for (i = 0; i < commit_graph->num_commits; i++) { const unsigned char *hash = commit_graph->chunk_oid_lookup + commit_graph->hash_len * i; diff --git a/object-store.h b/object-store.h index 0e13543babf4f8..e481f7ad41bd87 100644 --- a/object-store.h +++ b/object-store.h @@ -106,6 +106,9 @@ struct raw_object_store { */ struct oidmap *replace_map; + struct commit_graph *commit_graph; + unsigned commit_graph_attempted : 1; /* if loading has been attempted */ + /* * private data * diff --git a/object.c b/object.c index b0faab85d40ae8..e2c112cc1a757f 100644 --- a/object.c +++ b/object.c @@ -9,6 +9,7 @@ #include "alloc.h" #include "object-store.h" #include "packfile.h" +#include "commit-graph.h" unsigned int get_max_object_index(void) { @@ -507,6 +508,10 @@ void raw_object_store_clear(struct raw_object_store *o) oidmap_free(o->replace_map, 1); FREE_AND_NULL(o->replace_map); + free_commit_graph(o->commit_graph); + o->commit_graph = NULL; + o->commit_graph_attempted = 0; + free_alt_odbs(o); o->alt_odb_tail = NULL; From dade47c06cf849b0ca180a8e6383b55ea6f75812 Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Wed, 11 Jul 2018 15:42:42 -0700 Subject: [PATCH 6/6] commit-graph: add repo arg to graph readers Add a struct repository argument to the functions in commit-graph.h that read the commit graph. (This commit does not affect functions that write commit graphs.) Because the commit graph functions can now read the commit graph of any repository, the global variable core_commit_graph has been removed. Instead, the config option core.commitGraph is now read on the first time in a repository that a commit is attempted to be parsed using its commit graph. This commit includes a test that exercises the functionality on an arbitrary repository that is not the_repository. Signed-off-by: Jonathan Tan Signed-off-by: Junio C Hamano --- Makefile | 1 + builtin/fsck.c | 2 +- cache.h | 1 - commit-graph.c | 60 +++++++++++++++------------- commit-graph.h | 7 ++-- commit.c | 6 +-- config.c | 5 --- environment.c | 1 - ref-filter.c | 2 +- t/helper/test-repository.c | 82 ++++++++++++++++++++++++++++++++++++++ t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + t/t5318-commit-graph.sh | 35 ++++++++++++++++ 13 files changed, 162 insertions(+), 42 deletions(-) create mode 100644 t/helper/test-repository.c diff --git a/Makefile b/Makefile index 0cb6590f24acda..bb8bd672016ddb 100644 --- a/Makefile +++ b/Makefile @@ -719,6 +719,7 @@ TEST_BUILTINS_OBJS += test-prio-queue.o TEST_BUILTINS_OBJS += test-read-cache.o TEST_BUILTINS_OBJS += test-ref-store.o TEST_BUILTINS_OBJS += test-regex.o +TEST_BUILTINS_OBJS += test-repository.o TEST_BUILTINS_OBJS += test-revision-walking.o TEST_BUILTINS_OBJS += test-run-command.o TEST_BUILTINS_OBJS += test-scrap-cache-tree.o diff --git a/builtin/fsck.c b/builtin/fsck.c index ea5e2a03e6c882..c96f3f4fccea0b 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -830,7 +830,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) check_connectivity(); - if (core_commit_graph) { + if (!git_config_get_bool("core.commitgraph", &i) && i) { struct child_process commit_graph_verify = CHILD_PROCESS_INIT; const char *verify_argv[] = { "commit-graph", "verify", NULL, NULL, NULL }; diff --git a/cache.h b/cache.h index 8b447652a7e94a..3311f4c9e2711f 100644 --- a/cache.h +++ b/cache.h @@ -813,7 +813,6 @@ extern char *git_replace_ref_base; extern int fsync_object_files; extern int core_preload_index; -extern int core_commit_graph; extern int core_apply_sparse_checkout; extern int precomposed_unicode; extern int protect_hfs; diff --git a/commit-graph.c b/commit-graph.c index b6a76a1413f620..b0a55ad128fbca 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -183,15 +183,15 @@ struct commit_graph *load_commit_graph_one(const char *graph_file) exit(1); } -static void prepare_commit_graph_one(const char *obj_dir) +static void prepare_commit_graph_one(struct repository *r, const char *obj_dir) { char *graph_name; - if (the_repository->objects->commit_graph) + if (r->objects->commit_graph) return; graph_name = get_commit_graph_filename(obj_dir); - the_repository->objects->commit_graph = + r->objects->commit_graph = load_commit_graph_one(graph_name); FREE_AND_NULL(graph_name); @@ -203,26 +203,34 @@ static void prepare_commit_graph_one(const char *obj_dir) * On the first invocation, this function attemps to load the commit * graph if the_repository is configured to have one. */ -static int prepare_commit_graph(void) +static int prepare_commit_graph(struct repository *r) { struct alternate_object_database *alt; char *obj_dir; + int config_value; - if (the_repository->objects->commit_graph_attempted) - return !!the_repository->objects->commit_graph; - the_repository->objects->commit_graph_attempted = 1; + if (r->objects->commit_graph_attempted) + return !!r->objects->commit_graph; + r->objects->commit_graph_attempted = 1; - if (!core_commit_graph) + if (repo_config_get_bool(r, "core.commitgraph", &config_value) || + !config_value) + /* + * This repository is not configured to use commit graphs, so + * do not load one. (But report commit_graph_attempted anyway + * so that commit graph loading is not attempted again for this + * repository.) + */ return 0; - obj_dir = get_object_directory(); - prepare_commit_graph_one(obj_dir); - prepare_alt_odb(the_repository); - for (alt = the_repository->objects->alt_odb_list; - !the_repository->objects->commit_graph && alt; + obj_dir = r->objects->objectdir; + prepare_commit_graph_one(r, obj_dir); + prepare_alt_odb(r); + for (alt = r->objects->alt_odb_list; + !r->objects->commit_graph && alt; alt = alt->next) - prepare_commit_graph_one(alt->path); - return !!the_repository->objects->commit_graph; + prepare_commit_graph_one(r, alt->path); + return !!r->objects->commit_graph; } static void close_commit_graph(void) @@ -323,8 +331,6 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item { uint32_t pos; - if (!core_commit_graph) - return 0; if (item->object.parsed) return 1; @@ -334,20 +340,20 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item return 0; } -int parse_commit_in_graph(struct commit *item) +int parse_commit_in_graph(struct repository *r, struct commit *item) { - if (!prepare_commit_graph()) + if (!prepare_commit_graph(r)) return 0; - return parse_commit_in_graph_one(the_repository->objects->commit_graph, item); + return parse_commit_in_graph_one(r->objects->commit_graph, item); } -void load_commit_graph_info(struct commit *item) +void load_commit_graph_info(struct repository *r, struct commit *item) { uint32_t pos; - if (!prepare_commit_graph()) + if (!prepare_commit_graph(r)) return; - if (find_commit_in_graph(item, the_repository->objects->commit_graph, &pos)) - fill_commit_graph_info(item, the_repository->objects->commit_graph, pos); + if (find_commit_in_graph(item, r->objects->commit_graph, &pos)) + fill_commit_graph_info(item, r->objects->commit_graph, pos); } static struct tree *load_tree_for_commit(struct commit_graph *g, struct commit *c) @@ -373,9 +379,9 @@ static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g, return load_tree_for_commit(g, (struct commit *)c); } -struct tree *get_commit_tree_in_graph(const struct commit *c) +struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit *c) { - return get_commit_tree_in_graph_one(the_repository->objects->commit_graph, c); + return get_commit_tree_in_graph_one(r->objects->commit_graph, c); } static void write_graph_chunk_fanout(struct hashfile *f, @@ -691,7 +697,7 @@ void write_commit_graph(const char *obj_dir, oids.alloc = approximate_object_count() / 4; if (append) { - prepare_commit_graph_one(obj_dir); + prepare_commit_graph_one(the_repository, obj_dir); if (the_repository->objects->commit_graph) oids.alloc += the_repository->objects->commit_graph->num_commits; } diff --git a/commit-graph.h b/commit-graph.h index 94defb04a92478..76e098934a7f67 100644 --- a/commit-graph.h +++ b/commit-graph.h @@ -19,7 +19,7 @@ char *get_commit_graph_filename(const char *obj_dir); * * See parse_commit_buffer() for the fallback after this call. */ -int parse_commit_in_graph(struct commit *item); +int parse_commit_in_graph(struct repository *r, struct commit *item); /* * It is possible that we loaded commit contents from the commit buffer, @@ -27,9 +27,10 @@ int parse_commit_in_graph(struct commit *item); * checked and filled. Fill the graph_pos and generation members of * the given commit. */ -void load_commit_graph_info(struct commit *item); +void load_commit_graph_info(struct repository *r, struct commit *item); -struct tree *get_commit_tree_in_graph(const struct commit *c); +struct tree *get_commit_tree_in_graph(struct repository *r, + const struct commit *c); struct commit_graph { int graph_fd; diff --git a/commit.c b/commit.c index c0a83d2644c54a..39b80bd21d59ca 100644 --- a/commit.c +++ b/commit.c @@ -342,7 +342,7 @@ struct tree *get_commit_tree(const struct commit *commit) if (commit->graph_pos == COMMIT_NOT_FROM_GRAPH) BUG("commit has NULL tree, but was not loaded from commit-graph"); - return get_commit_tree_in_graph(commit); + return get_commit_tree_in_graph(the_repository, commit); } struct object_id *get_commit_tree_oid(const struct commit *commit) @@ -438,7 +438,7 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b item->date = parse_commit_date(bufptr, tail); if (check_graph) - load_commit_graph_info(item); + load_commit_graph_info(the_repository, item); return 0; } @@ -454,7 +454,7 @@ int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_com return -1; if (item->object.parsed) return 0; - if (use_commit_graph && parse_commit_in_graph(item)) + if (use_commit_graph && parse_commit_in_graph(the_repository, item)) return 0; buffer = read_object_file(&item->object.oid, &type, &size); if (!buffer) diff --git a/config.c b/config.c index 139c903f6b3f1f..3aacddfec4b9dd 100644 --- a/config.c +++ b/config.c @@ -1309,11 +1309,6 @@ static int git_default_core_config(const char *var, const char *value) return 0; } - if (!strcmp(var, "core.commitgraph")) { - core_commit_graph = git_config_bool(var, value); - return 0; - } - if (!strcmp(var, "core.sparsecheckout")) { core_apply_sparse_checkout = git_config_bool(var, value); return 0; diff --git a/environment.c b/environment.c index 013e845235ea88..6cf00793894f75 100644 --- a/environment.c +++ b/environment.c @@ -66,7 +66,6 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED; enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE; char *notes_ref_name; int grafts_replace_parents = 1; -int core_commit_graph; int core_apply_sparse_checkout; int merge_log_config = -1; int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */ diff --git a/ref-filter.c b/ref-filter.c index 49021ee4467de5..9b2da883926dce 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -1713,7 +1713,7 @@ static enum contains_result contains_tag_algo(struct commit *candidate, for (p = want; p; p = p->next) { struct commit *c = p->item; - load_commit_graph_info(c); + load_commit_graph_info(the_repository, c); if (c->generation < cutoff) cutoff = c->generation; } diff --git a/t/helper/test-repository.c b/t/helper/test-repository.c new file mode 100644 index 00000000000000..2762ca656262ba --- /dev/null +++ b/t/helper/test-repository.c @@ -0,0 +1,82 @@ +#include "test-tool.h" +#include "cache.h" +#include "commit-graph.h" +#include "commit.h" +#include "config.h" +#include "object-store.h" +#include "object.h" +#include "repository.h" +#include "tree.h" + +static void test_parse_commit_in_graph(const char *gitdir, const char *worktree, + const struct object_id *commit_oid) +{ + struct repository r; + struct commit *c; + struct commit_list *parent; + + repo_init(&r, gitdir, worktree); + + c = lookup_commit(&r, commit_oid); + + if (!parse_commit_in_graph(&r, c)) + die("Couldn't parse commit"); + + printf("%"PRItime, c->date); + for (parent = c->parents; parent; parent = parent->next) + printf(" %s", oid_to_hex(&parent->item->object.oid)); + printf("\n"); + + repo_clear(&r); +} + +static void test_get_commit_tree_in_graph(const char *gitdir, + const char *worktree, + const struct object_id *commit_oid) +{ + struct repository r; + struct commit *c; + struct tree *tree; + + repo_init(&r, gitdir, worktree); + + c = lookup_commit(&r, commit_oid); + + /* + * get_commit_tree_in_graph does not automatically parse the commit, so + * parse it first. + */ + if (!parse_commit_in_graph(&r, c)) + die("Couldn't parse commit"); + tree = get_commit_tree_in_graph(&r, c); + if (!tree) + die("Couldn't get commit tree"); + + printf("%s\n", oid_to_hex(&tree->object.oid)); + + repo_clear(&r); +} + +int cmd__repository(int argc, const char **argv) +{ + if (argc < 2) + die("must have at least 2 arguments"); + if (!strcmp(argv[1], "parse_commit_in_graph")) { + struct object_id oid; + if (argc < 5) + die("not enough arguments"); + if (parse_oid_hex(argv[4], &oid, &argv[4])) + die("cannot parse oid '%s'", argv[4]); + test_parse_commit_in_graph(argv[2], argv[3], &oid); + } else if (!strcmp(argv[1], "get_commit_tree_in_graph")) { + struct object_id oid; + if (argc < 5) + die("not enough arguments"); + if (parse_oid_hex(argv[4], &oid, &argv[4])) + die("cannot parse oid '%s'", argv[4]); + test_get_commit_tree_in_graph(argv[2], argv[3], &oid); + } else { + die("unrecognized '%s'", argv[1]); + } + return 0; +} diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 805a45de9c877d..dafc91c240a440 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -29,6 +29,7 @@ static struct test_cmd cmds[] = { { "read-cache", cmd__read_cache }, { "ref-store", cmd__ref_store }, { "regex", cmd__regex }, + { "repository", cmd__repository }, { "revision-walking", cmd__revision_walking }, { "run-command", cmd__run_command }, { "scrap-cache-tree", cmd__scrap_cache_tree }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index 7116ddfb94398d..80cbcf08575d5e 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -23,6 +23,7 @@ int cmd__prio_queue(int argc, const char **argv); int cmd__read_cache(int argc, const char **argv); int cmd__ref_store(int argc, const char **argv); int cmd__regex(int argc, const char **argv); +int cmd__repository(int argc, const char **argv); int cmd__revision_walking(int argc, const char **argv); int cmd__run_command(int argc, const char **argv); int cmd__scrap_cache_tree(int argc, const char **argv); diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 5947de3d2438ea..4f17d7701e456b 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -431,4 +431,39 @@ test_expect_success 'git fsck (checks commit-graph)' ' test_must_fail git fsck ' +test_expect_success 'setup non-the_repository tests' ' + rm -rf repo && + git init repo && + test_commit -C repo one && + test_commit -C repo two && + git -C repo config core.commitGraph true && + git -C repo rev-parse two | \ + git -C repo commit-graph write --stdin-commits +' + +test_expect_success 'parse_commit_in_graph works for non-the_repository' ' + test-tool repository parse_commit_in_graph \ + repo/.git repo "$(git -C repo rev-parse two)" >actual && + echo $(git -C repo log --pretty="%ct" -1) \ + $(git -C repo rev-parse one) >expect && + test_cmp expect actual && + + test-tool repository parse_commit_in_graph \ + repo/.git repo "$(git -C repo rev-parse one)" >actual && + echo $(git -C repo log --pretty="%ct" -1 one) >expect && + test_cmp expect actual +' + +test_expect_success 'get_commit_tree_in_graph works for non-the_repository' ' + test-tool repository get_commit_tree_in_graph \ + repo/.git repo "$(git -C repo rev-parse two)" >actual && + echo $(git -C repo rev-parse two^{tree}) >expect && + test_cmp expect actual && + + test-tool repository get_commit_tree_in_graph \ + repo/.git repo "$(git -C repo rev-parse one)" >actual && + echo $(git -C repo rev-parse one^{tree}) >expect && + test_cmp expect actual +' + test_done