commit-graph: be extra careful about mixed generations

When upgrading to a commit-graph with corrected commit dates from one without, there are a few things that need to be considered. When computing generation numbers for the new commit-graph file that expects to add the generation_data chunk with corrected commit dates, we need to ensure that the 'generation' member of the commit_graph_data struct is set to zero for these commits. Unfortunately, the fallback to use topological level for generation number when corrected commit dates are not available are causing us harm here: parsing commits notices that read_generation_data is false and populates 'generation' with the topological level. The solution is to iterate through the commits, parse the commits to populate initial values, then reset the generation values to zero to trigger recalculation. This loop only occurs when the existing commit-graph data has no corrected commit dates. While this improves our situation somewhat, we have not completely solved the issue for correctly computing generation numbers for mixed layers. That follows in the next change. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Feb 2, 2021 at 03:01 UTC fde55b0906552537c8cbcbf654f8e9dd64414637
1 file changed +12 -2
commit-graph.c
+12 -2
@@ -1036,7 +1036,8 @@ struct write_commit_graph_context {
1036 split:1,
1037 changed_paths:1,
1038 order_by_pack:1,
1039 - write_generation_data:1;
1039 + write_generation_data:1,
1040 + trust_generation_numbers:1;
1041
1042 struct topo_level_slab *topo_levels;
1043 const struct commit_graph_opts *opts;
@@ -1508,6 +1509,15 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
1509 ctx->progress = start_delayed_progress(
1510 _("Computing commit graph generation numbers"),
1511 ctx->commits.nr);
1512 +
1513 + if (!ctx->trust_generation_numbers) {
1514 + for (i = 0; i < ctx->commits.nr; i++) {
1515 + struct commit *c = ctx->commits.list[i];
1516 + repo_parse_commit(ctx->r, c);
1517 + commit_graph_data_at(c)->generation = GENERATION_NUMBER_ZERO;
1518 + }
1519 + }
1520 +
1521 for (i = 0; i < ctx->commits.nr; i++) {
1522 struct commit *c = ctx->commits.list[i];
1523 timestamp_t corrected_commit_date;
@@ -2439,7 +2449,7 @@ int write_commit_graph(struct object_directory *odb,
2449 } else
2450 ctx->num_commit_graphs_after = 1;
2451
2442 - validate_mixed_generation_chain(ctx->r->objects->commit_graph);
2452 + ctx->trust_generation_numbers = validate_mixed_generation_chain(ctx->r->objects->commit_graph);
2453
2454 compute_topological_levels(ctx);
2455 if (ctx->write_generation_data)