diff options
Diffstat (limited to 'commit-graph.c')
-rw-r--r-- | commit-graph.c | 70 |
1 files changed, 45 insertions, 25 deletions
diff --git a/commit-graph.c b/commit-graph.c index 9b02d2c..0aea7b2 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -41,6 +41,9 @@ #define GRAPH_MIN_SIZE (GRAPH_HEADER_SIZE + 4 * GRAPH_CHUNKLOOKUP_WIDTH \ + GRAPH_FANOUT_SIZE + the_hash_algo->rawsz) +/* Remember to update object flag allocation in object.h */ +#define REACHABLE (1u<<15) + char *get_commit_graph_filename(const char *obj_dir) { char *filename = xstrfmt("%s/info/commit-graph", obj_dir); @@ -468,14 +471,21 @@ static int prepare_commit_graph(struct repository *r) { struct object_directory *odb; - if (git_env_bool(GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD, 0)) - die("dying as requested by the '%s' variable on commit-graph load!", - GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD); + /* + * This must come before the "already attempted?" check below, because + * we want to disable even an already-loaded graph file. + */ + if (r->commit_graph_disabled) + return 0; if (r->objects->commit_graph_attempted) return !!r->objects->commit_graph; r->objects->commit_graph_attempted = 1; + if (git_env_bool(GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD, 0)) + die("dying as requested by the '%s' variable on commit-graph load!", + GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD); + prepare_repo_settings(r); if (!git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) && @@ -839,12 +849,19 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len, while (list < last) { struct commit_list *parent; + struct object_id *tree; int edge_value; uint32_t packedDate[2]; display_progress(ctx->progress, ++ctx->progress_cnt); - parse_commit_no_graph(*list); - hashwrite(f, get_commit_tree_oid(*list)->hash, hash_len); + if (parse_commit_no_graph(*list)) + die(_("unable to parse commit %s"), + oid_to_hex(&(*list)->object.oid)); + tree = get_commit_tree_oid(*list); + if (!tree) + die(_("unable to get tree for %s"), + oid_to_hex(&(*list)->object.oid)); + hashwrite(f, tree->hash, hash_len); parent = (*list)->parents; @@ -1016,11 +1033,11 @@ static void add_missing_parents(struct write_commit_graph_context *ctx, struct c { struct commit_list *parent; for (parent = commit->parents; parent; parent = parent->next) { - if (!(parent->item->object.flags & UNINTERESTING)) { + if (!(parent->item->object.flags & REACHABLE)) { ALLOC_GROW(ctx->oids.list, ctx->oids.nr + 1, ctx->oids.alloc); oidcpy(&ctx->oids.list[ctx->oids.nr], &(parent->item->object.oid)); ctx->oids.nr++; - parent->item->object.flags |= UNINTERESTING; + parent->item->object.flags |= REACHABLE; } } } @@ -1038,7 +1055,7 @@ static void close_reachable(struct write_commit_graph_context *ctx) display_progress(ctx->progress, i + 1); commit = lookup_commit(ctx->r, &ctx->oids.list[i]); if (commit) - commit->object.flags |= UNINTERESTING; + commit->object.flags |= REACHABLE; } stop_progress(&ctx->progress); @@ -1050,7 +1067,7 @@ static void close_reachable(struct write_commit_graph_context *ctx) if (ctx->report_progress) ctx->progress = start_delayed_progress( _("Expanding reachable commits in commit graph"), - ctx->oids.nr); + 0); for (i = 0; i < ctx->oids.nr; i++) { display_progress(ctx->progress, i + 1); commit = lookup_commit(ctx->r, &ctx->oids.list[i]); @@ -1075,7 +1092,7 @@ static void close_reachable(struct write_commit_graph_context *ctx) commit = lookup_commit(ctx->r, &ctx->oids.list[i]); if (commit) - commit->object.flags &= ~UNINTERESTING; + commit->object.flags &= ~REACHABLE; } stop_progress(&ctx->progress); } @@ -1279,7 +1296,6 @@ static uint32_t count_distinct_commits(struct write_commit_graph_context *ctx) static void copy_oids_to_commits(struct write_commit_graph_context *ctx) { uint32_t i; - struct commit_list *parent; ctx->num_extra_edges = 0; if (ctx->report_progress) @@ -1287,7 +1303,8 @@ static void copy_oids_to_commits(struct write_commit_graph_context *ctx) _("Finding extra edges in commit graph"), ctx->oids.nr); for (i = 0; i < ctx->oids.nr; i++) { - int num_parents = 0; + unsigned int num_parents; + display_progress(ctx->progress, i + 1); if (i > 0 && oideq(&ctx->oids.list[i - 1], &ctx->oids.list[i])) continue; @@ -1301,10 +1318,7 @@ static void copy_oids_to_commits(struct write_commit_graph_context *ctx) parse_commit_no_graph(ctx->commits.list[ctx->commits.nr]); - for (parent = ctx->commits.list[ctx->commits.nr]->parents; - parent; parent = parent->next) - num_parents++; - + num_parents = commit_list_count(ctx->commits.list[ctx->commits.nr]->parents); if (num_parents > 2) ctx->num_extra_edges += num_parents - 1; @@ -1522,8 +1536,8 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) static void split_graph_merge_strategy(struct write_commit_graph_context *ctx) { - struct commit_graph *g = ctx->r->objects->commit_graph; - uint32_t num_commits = ctx->commits.nr; + struct commit_graph *g; + uint32_t num_commits; uint32_t i; int max_commits = 0; @@ -1535,6 +1549,7 @@ static void split_graph_merge_strategy(struct write_commit_graph_context *ctx) } g = ctx->r->objects->commit_graph; + num_commits = ctx->commits.nr; ctx->num_commit_graphs_after = ctx->num_commit_graphs_before + 1; while (g && (g->num_commits <= size_mult * num_commits || @@ -1616,8 +1631,7 @@ static int commit_compare(const void *_a, const void *_b) static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx) { - uint32_t i, num_parents; - struct commit_list *parent; + uint32_t i; if (ctx->report_progress) ctx->progress = start_delayed_progress( @@ -1635,10 +1649,9 @@ static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx) die(_("unexpected duplicate commit id %s"), oid_to_hex(&ctx->commits.list[i]->object.oid)); } else { - num_parents = 0; - for (parent = ctx->commits.list[i]->parents; parent; parent = parent->next) - num_parents++; + unsigned int num_parents; + num_parents = commit_list_count(ctx->commits.list[i]->parents); if (num_parents > 2) ctx->num_extra_edges += num_parents - 1; } @@ -1992,8 +2005,10 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags) if (verify_commit_graph_error & ~VERIFY_COMMIT_GRAPH_ERROR_HASH) return verify_commit_graph_error; - progress = start_progress(_("Verifying commits in commit graph"), - g->num_commits); + if (flags & COMMIT_GRAPH_WRITE_PROGRESS) + progress = start_progress(_("Verifying commits in commit graph"), + g->num_commits); + for (i = 0; i < g->num_commits; i++) { struct commit *graph_commit, *odb_commit; struct commit_list *graph_parents, *odb_parents; @@ -2101,3 +2116,8 @@ void free_commit_graph(struct commit_graph *g) free(g->filename); free(g); } + +void disable_commit_graph(struct repository *r) +{ + r->commit_graph_disabled = 1; +} |