diff options
Diffstat (limited to 'commit-graph.c')
-rw-r--r-- | commit-graph.c | 148 |
1 files changed, 81 insertions, 67 deletions
diff --git a/commit-graph.c b/commit-graph.c index 212232e752..8a1bec7b8a 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -80,28 +80,28 @@ struct commit_graph *load_commit_graph_one(const char *graph_file) if (graph_size < GRAPH_MIN_SIZE) { close(fd); - die("graph file %s is too small", graph_file); + die(_("graph file %s is too small"), graph_file); } graph_map = xmmap(NULL, graph_size, PROT_READ, MAP_PRIVATE, fd, 0); data = (const unsigned char *)graph_map; graph_signature = get_be32(data); if (graph_signature != GRAPH_SIGNATURE) { - error("graph signature %X does not match signature %X", + error(_("graph signature %X does not match signature %X"), graph_signature, GRAPH_SIGNATURE); goto cleanup_fail; } graph_version = *(unsigned char*)(data + 4); if (graph_version != GRAPH_VERSION) { - error("graph version %X does not match version %X", + error(_("graph version %X does not match version %X"), graph_version, GRAPH_VERSION); goto cleanup_fail; } hash_version = *(unsigned char*)(data + 5); if (hash_version != GRAPH_OID_VERSION) { - error("hash version %X does not match version %X", + error(_("hash version %X does not match version %X"), hash_version, GRAPH_OID_VERSION); goto cleanup_fail; } @@ -125,7 +125,7 @@ struct commit_graph *load_commit_graph_one(const char *graph_file) chunk_lookup += GRAPH_CHUNKLOOKUP_WIDTH; if (chunk_offset > graph_size - GIT_MAX_RAWSZ) { - error("improper chunk offset %08x%08x", (uint32_t)(chunk_offset >> 32), + error(_("improper chunk offset %08x%08x"), (uint32_t)(chunk_offset >> 32), (uint32_t)chunk_offset); goto cleanup_fail; } @@ -161,7 +161,7 @@ struct commit_graph *load_commit_graph_one(const char *graph_file) } if (chunk_repeated) { - error("chunk id %08x appears multiple times", chunk_id); + error(_("chunk id %08x appears multiple times"), chunk_id); goto cleanup_fail; } @@ -183,53 +183,60 @@ cleanup_fail: exit(1); } -/* global storage */ -static struct commit_graph *commit_graph = NULL; - -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 (commit_graph) + if (r->objects->commit_graph) return; graph_name = get_commit_graph_filename(obj_dir); - commit_graph = load_commit_graph_one(graph_name); + r->objects->commit_graph = + load_commit_graph_one(graph_name); FREE_AND_NULL(graph_name); } -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(struct repository *r) { struct alternate_object_database *alt; char *obj_dir; + int config_value; - if (prepare_commit_graph_run_once) - return; - prepare_commit_graph_run_once = 1; + if (r->objects->commit_graph_attempted) + return !!r->objects->commit_graph; + r->objects->commit_graph_attempted = 1; - obj_dir = get_object_directory(); - prepare_commit_graph_one(obj_dir); - prepare_alt_odb(the_repository); - for (alt = the_repository->objects->alt_odb_list; - !commit_graph && alt; + 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 = 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); + prepare_commit_graph_one(r, alt->path); + return !!r->objects->commit_graph; } 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(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) @@ -249,9 +256,9 @@ static struct commit_list **insert_parent_or_die(struct commit_graph *g, die("invalid parent position %"PRIu64, pos); hashcpy(oid.hash, g->chunk_oid_lookup + g->hash_len * pos); - c = lookup_commit(&oid); + c = lookup_commit(the_repository, &oid); if (!c) - die("could not find commit %s", oid_to_hex(&oid)); + die(_("could not find commit %s"), oid_to_hex(&oid)); c->graph_pos = pos; return &commit_list_insert(c, pptr)->next; } @@ -324,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; @@ -335,25 +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 (!core_commit_graph) + if (!prepare_commit_graph(r)) 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(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 (!core_commit_graph) + if (!prepare_commit_graph(r)) return; - prepare_commit_graph(); - if (commit_graph && find_commit_in_graph(item, commit_graph, &pos)) - fill_commit_graph_info(item, 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) @@ -363,7 +363,7 @@ static struct tree *load_tree_for_commit(struct commit_graph *g, struct commit * GRAPH_DATA_WIDTH * (c->graph_pos); hashcpy(oid.hash, commit_data); - c->maybe_tree = lookup_tree(&oid); + c->maybe_tree = lookup_tree(the_repository, &oid); return c->maybe_tree; } @@ -379,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(commit_graph, c); + return get_commit_tree_in_graph_one(r->objects->commit_graph, c); } static void write_graph_chunk_fanout(struct hashfile *f, @@ -562,7 +562,7 @@ static int add_packed_commits(const struct object_id *oid, oi.typep = &type; if (packed_object_info(the_repository, pack, offset, &oi) < 0) - die("unable to get type of object %s", oid_to_hex(oid)); + die(_("unable to get type of object %s"), oid_to_hex(oid)); if (type != OBJ_COMMIT) return 0; @@ -593,7 +593,7 @@ static void close_reachable(struct packed_oid_list *oids) struct commit *commit; for (i = 0; i < oids->nr; i++) { - commit = lookup_commit(&oids->list[i]); + commit = lookup_commit(the_repository, &oids->list[i]); if (commit) commit->object.flags |= UNINTERESTING; } @@ -604,14 +604,14 @@ static void close_reachable(struct packed_oid_list *oids) * closure. */ for (i = 0; i < oids->nr; i++) { - commit = lookup_commit(&oids->list[i]); + commit = lookup_commit(the_repository, &oids->list[i]); if (commit && !parse_commit(commit)) add_missing_parents(oids, commit); } for (i = 0; i < oids->nr; i++) { - commit = lookup_commit(&oids->list[i]); + commit = lookup_commit(the_repository, &oids->list[i]); if (commit) commit->object.flags &= ~UNINTERESTING; @@ -697,16 +697,18 @@ void write_commit_graph(const char *obj_dir, oids.alloc = approximate_object_count() / 4; if (append) { - prepare_commit_graph_one(obj_dir); - if (commit_graph) - oids.alloc += commit_graph->num_commits; + prepare_commit_graph_one(the_repository, obj_dir); + 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; @@ -725,10 +727,10 @@ void write_commit_graph(const char *obj_dir, strbuf_addstr(&packname, pack_indexes->items[i].string); p = add_packed_git(packname.buf, packname.len, 1); if (!p) - die("error adding pack %s", packname.buf); + die(_("error adding pack %s"), packname.buf); if (open_pack_index(p)) - die("error opening index for %s", packname.buf); - for_each_object_in_pack(p, add_packed_commits, &oids); + die(_("error opening index for %s"), packname.buf); + for_each_object_in_pack(p, add_packed_commits, &oids, 0); close_pack(p); } strbuf_release(&packname); @@ -744,7 +746,7 @@ void write_commit_graph(const char *obj_dir, parse_oid_hex(commit_hex->items[i].string, &oid, &end)) continue; - result = lookup_commit_reference_gently(&oid, 1); + result = lookup_commit_reference_gently(the_repository, &oid, 1); if (result) { ALLOC_GROW(oids.list, oids.nr + 1, oids.alloc); @@ -780,7 +782,7 @@ void write_commit_graph(const char *obj_dir, if (i > 0 && !oidcmp(&oids.list[i-1], &oids.list[i])) continue; - commits.list[commits.nr] = lookup_commit(&oids.list[i]); + commits.list[commits.nr] = lookup_commit(the_repository, &oids.list[i]); parse_commit(commits.list[commits.nr]); for (parent = commits.list[commits.nr]->parents; @@ -924,7 +926,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g) cur_fanout_pos++; } - graph_commit = lookup_commit(&cur_oid); + graph_commit = lookup_commit(r, &cur_oid); if (!parse_commit_in_graph_one(g, graph_commit)) graph_report("failed to parse %s from commit-graph", oid_to_hex(&cur_oid)); @@ -950,7 +952,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g) hashcpy(cur_oid.hash, g->chunk_oid_lookup + g->hash_len * i); - graph_commit = lookup_commit(&cur_oid); + graph_commit = lookup_commit(r, &cur_oid); odb_commit = (struct commit *)create_object(r, cur_oid.hash, alloc_commit_node(r)); if (parse_commit_internal(odb_commit, 0, 0)) { graph_report("failed to parse %s from object database", @@ -1027,3 +1029,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); +} |