diff options
Diffstat (limited to 'commit-graph.c')
-rw-r--r-- | commit-graph.c | 109 |
1 files changed, 69 insertions, 40 deletions
diff --git a/commit-graph.c b/commit-graph.c index f18380b922..00614acd65 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -425,7 +425,7 @@ struct commit_graph *parse_commit_graph(struct repository *r, FREE_AND_NULL(graph->bloom_filter_settings); } - hashcpy(graph->oid.hash, graph->data + graph->data_len - graph->hash_len); + oidread(&graph->oid, graph->data + graph->data_len - graph->hash_len); if (verify_commit_graph_lite(graph)) goto free_and_return; @@ -723,7 +723,7 @@ void close_commit_graph(struct raw_object_store *o) o->commit_graph = NULL; } -static int bsearch_graph(struct commit_graph *g, struct object_id *oid, uint32_t *pos) +static int bsearch_graph(struct commit_graph *g, const struct object_id *oid, uint32_t *pos) { return bsearch_hash(oid->hash, g->chunk_oid_fanout, g->chunk_oid_lookup, g->hash_len, pos); @@ -746,7 +746,7 @@ static void load_oid_from_graph(struct commit_graph *g, lex_index = pos - g->num_commits_in_base; - hashcpy(oid->hash, g->chunk_oid_lookup + g->hash_len * lex_index); + oidread(oid, g->chunk_oid_lookup + g->hash_len * lex_index); } static struct commit_list **insert_parent_or_die(struct repository *r, @@ -864,26 +864,55 @@ static int fill_commit_in_graph(struct repository *r, return 1; } -static int find_commit_in_graph(struct commit *item, struct commit_graph *g, uint32_t *pos) +static int search_commit_pos_in_graph(const struct object_id *id, struct commit_graph *g, uint32_t *pos) +{ + struct commit_graph *cur_g = g; + uint32_t lex_index; + + while (cur_g && !bsearch_graph(cur_g, id, &lex_index)) + cur_g = cur_g->base_graph; + + if (cur_g) { + *pos = lex_index + cur_g->num_commits_in_base; + return 1; + } + + return 0; +} + +static int find_commit_pos_in_graph(struct commit *item, struct commit_graph *g, uint32_t *pos) { uint32_t graph_pos = commit_graph_position(item); if (graph_pos != COMMIT_NOT_FROM_GRAPH) { *pos = graph_pos; return 1; } else { - struct commit_graph *cur_g = g; - uint32_t lex_index; + return search_commit_pos_in_graph(&item->object.oid, g, pos); + } +} - while (cur_g && !bsearch_graph(cur_g, &(item->object.oid), &lex_index)) - cur_g = cur_g->base_graph; +struct commit *lookup_commit_in_graph(struct repository *repo, const struct object_id *id) +{ + struct commit *commit; + uint32_t pos; - if (cur_g) { - *pos = lex_index + cur_g->num_commits_in_base; - return 1; - } + if (!repo->objects->commit_graph) + return NULL; + if (!search_commit_pos_in_graph(id, repo->objects->commit_graph, &pos)) + return NULL; + if (!repo_has_object_file(repo, id)) + return NULL; - return 0; - } + commit = lookup_commit(repo, id); + if (!commit) + return NULL; + if (commit->object.parsed) + return commit; + + if (!fill_commit_in_graph(repo, commit, repo->objects->commit_graph, pos)) + return NULL; + + return commit; } static int parse_commit_in_graph_one(struct repository *r, @@ -895,7 +924,7 @@ static int parse_commit_in_graph_one(struct repository *r, if (item->object.parsed) return 1; - if (find_commit_in_graph(item, g, &pos)) + if (find_commit_pos_in_graph(item, g, &pos)) return fill_commit_in_graph(r, item, g, pos); return 0; @@ -921,7 +950,7 @@ void load_commit_graph_info(struct repository *r, struct commit *item) uint32_t pos; if (!prepare_commit_graph(r)) return; - if (find_commit_in_graph(item, r->objects->commit_graph, &pos)) + if (find_commit_pos_in_graph(item, r->objects->commit_graph, &pos)) fill_commit_graph_info(item, r->objects->commit_graph, pos); } @@ -939,7 +968,7 @@ static struct tree *load_tree_for_commit(struct repository *r, commit_data = g->chunk_commit_data + GRAPH_DATA_WIDTH * (graph_pos - g->num_commits_in_base); - hashcpy(oid.hash, commit_data); + oidread(&oid, commit_data); set_commit_tree(c, lookup_tree(r, &oid)); return c->maybe_tree; @@ -1091,9 +1120,9 @@ static int write_graph_chunk_data(struct hashfile *f, edge_value += ctx->new_num_commits_in_base; else if (ctx->new_base_graph) { uint32_t pos; - if (find_commit_in_graph(parent->item, - ctx->new_base_graph, - &pos)) + if (find_commit_pos_in_graph(parent->item, + ctx->new_base_graph, + &pos)) edge_value = pos; } @@ -1122,9 +1151,9 @@ static int write_graph_chunk_data(struct hashfile *f, edge_value += ctx->new_num_commits_in_base; else if (ctx->new_base_graph) { uint32_t pos; - if (find_commit_in_graph(parent->item, - ctx->new_base_graph, - &pos)) + if (find_commit_pos_in_graph(parent->item, + ctx->new_base_graph, + &pos)) edge_value = pos; } @@ -1235,9 +1264,9 @@ static int write_graph_chunk_extra_edges(struct hashfile *f, edge_value += ctx->new_num_commits_in_base; else if (ctx->new_base_graph) { uint32_t pos; - if (find_commit_in_graph(parent->item, - ctx->new_base_graph, - &pos)) + if (find_commit_pos_in_graph(parent->item, + ctx->new_base_graph, + &pos)) edge_value = pos; } @@ -1793,8 +1822,8 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) struct lock_file lk = LOCK_INIT; const unsigned hashsz = the_hash_algo->rawsz; struct strbuf progress_title = STRBUF_INIT; - struct object_id file_hash; struct chunkfile *cf; + unsigned char file_hash[GIT_MAX_RAWSZ]; if (ctx->split) { struct strbuf tmp_file = STRBUF_INIT; @@ -1909,7 +1938,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) } close_commit_graph(ctx->r->objects); - finalize_hashfile(f, file_hash.hash, CSUM_HASH_IN_STREAM | CSUM_FSYNC); + finalize_hashfile(f, file_hash, CSUM_HASH_IN_STREAM | CSUM_FSYNC); free_chunkfile(cf); if (ctx->split) { @@ -1945,7 +1974,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) unlink(graph_name); } - ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1] = xstrdup(oid_to_hex(&file_hash)); + ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1] = xstrdup(hash_to_hex(file_hash)); final_graph_name = get_split_graph_filename(ctx->odb, ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]); ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 1] = final_graph_name; @@ -2322,7 +2351,7 @@ int write_commit_graph(struct object_directory *odb, struct commit_graph *g = ctx->r->objects->commit_graph; for (i = 0; i < g->num_commits; i++) { struct object_id oid; - hashcpy(oid.hash, g->chunk_oid_lookup + g->hash_len * i); + oidread(&oid, g->chunk_oid_lookup + g->hash_len * i); oid_array_append(&ctx->oids, &oid); } } @@ -2408,6 +2437,7 @@ cleanup: #define VERIFY_COMMIT_GRAPH_ERROR_HASH 2 static int verify_commit_graph_error; +__attribute__((format (printf, 1, 2))) static void graph_report(const char *fmt, ...) { va_list ap; @@ -2422,13 +2452,16 @@ static void graph_report(const char *fmt, ...) #define GENERATION_ZERO_EXISTS 1 #define GENERATION_NUMBER_EXISTS 2 +static int commit_graph_checksum_valid(struct commit_graph *g) +{ + return hashfile_checksum_valid(g->data, g->data_len); +} + int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags) { uint32_t i, cur_fanout_pos = 0; - struct object_id prev_oid, cur_oid, checksum; + struct object_id prev_oid, cur_oid; int generation_zero = 0; - struct hashfile *f; - int devnull; struct progress *progress = NULL; int local_error = 0; @@ -2441,11 +2474,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags) if (verify_commit_graph_error) return verify_commit_graph_error; - devnull = open("/dev/null", O_WRONLY); - f = hashfd(devnull, NULL); - hashwrite(f, g->data, g->data_len - g->hash_len); - finalize_hashfile(f, checksum.hash, CSUM_CLOSE); - if (!hasheq(checksum.hash, g->data + g->data_len - g->hash_len)) { + if (!commit_graph_checksum_valid(g)) { graph_report(_("the commit-graph file has incorrect checksum and is likely corrupt")); verify_commit_graph_error = VERIFY_COMMIT_GRAPH_ERROR_HASH; } @@ -2453,7 +2482,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags) for (i = 0; i < g->num_commits; i++) { struct commit *graph_commit; - hashcpy(cur_oid.hash, g->chunk_oid_lookup + g->hash_len * i); + oidread(&cur_oid, g->chunk_oid_lookup + g->hash_len * i); if (i && oidcmp(&prev_oid, &cur_oid) >= 0) graph_report(_("commit-graph has incorrect OID order: %s then %s"), @@ -2501,7 +2530,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags) timestamp_t generation; display_progress(progress, i + 1); - hashcpy(cur_oid.hash, g->chunk_oid_lookup + g->hash_len * i); + oidread(&cur_oid, g->chunk_oid_lookup + g->hash_len * i); graph_commit = lookup_commit(r, &cur_oid); odb_commit = (struct commit *)create_object(r, &cur_oid, alloc_commit_node(r)); |