Skip to content

Commit 1e7561c

Browse files
abhishekkumar2718gitster
authored andcommitted
commit-graph: implement corrected commit date
With most of preparations done, let's implement corrected commit date. The corrected commit date for a commit is defined as: * A commit with no parents (a root commit) has corrected commit date equal to its committer date. * A commit with at least one parent has corrected commit date equal to the maximum of its commit date and one more than the largest corrected commit date among its parents. As a special case, a root commit with timestamp of zero (01.01.1970 00:00:00Z) has corrected commit date of one, to be able to distinguish from GENERATION_NUMBER_ZERO (that is, an uncomputed corrected commit date). To minimize the space required to store corrected commit date, Git stores corrected commit date offsets into the commit-graph file. The corrected commit date offset for a commit is defined as the difference between its corrected commit date and actual commit date. Storing corrected commit date requires sizeof(timestamp_t) bytes, which in most cases is 64 bits (uintmax_t). However, corrected commit date offsets can be safely stored using only 32-bits. This halves the size of GDAT chunk, which is a reduction of around 6% in the size of commit-graph file. However, using offsets be problematic if one of commits is malformed but valid and has committerdate of 0 Unix time, as the offset would be the same as corrected commit date and thus require 64-bits to be stored properly. While Git does not write out offsets at this stage, Git stores the corrected commit dates in member generation of struct commit_graph_data. It will begin writing commit date offsets with the introduction of generation data chunk. Signed-off-by: Abhishek Kumar <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f39cc49 commit 1e7561c

File tree

1 file changed

+23
-20
lines changed

1 file changed

+23
-20
lines changed

commit-graph.c

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,6 @@ static int commit_gen_cmp(const void *va, const void *vb)
154154
else if (generation_a > generation_b)
155155
return 1;
156156

157-
/* use date as a heuristic when generations are equal */
158-
if (a->date < b->date)
159-
return -1;
160-
else if (a->date > b->date)
161-
return 1;
162157
return 0;
163158
}
164159

@@ -1357,10 +1352,14 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
13571352
ctx->commits.nr);
13581353
for (i = 0; i < ctx->commits.nr; i++) {
13591354
timestamp_t level = *topo_level_slab_at(ctx->topo_levels, ctx->commits.list[i]);
1355+
timestamp_t corrected_commit_date = commit_graph_data_at(ctx->commits.list[i])->generation;
13601356

13611357
display_progress(ctx->progress, i + 1);
13621358
if (level != GENERATION_NUMBER_INFINITY &&
1363-
level != GENERATION_NUMBER_ZERO)
1359+
level != GENERATION_NUMBER_ZERO &&
1360+
corrected_commit_date != GENERATION_NUMBER_INFINITY &&
1361+
corrected_commit_date != GENERATION_NUMBER_ZERO
1362+
)
13641363
continue;
13651364

13661365
commit_list_insert(ctx->commits.list[i], &list);
@@ -1369,17 +1368,25 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
13691368
struct commit_list *parent;
13701369
int all_parents_computed = 1;
13711370
uint32_t max_level = 0;
1371+
timestamp_t max_corrected_commit_date = 0;
13721372

13731373
for (parent = current->parents; parent; parent = parent->next) {
13741374
level = *topo_level_slab_at(ctx->topo_levels, parent->item);
1375-
1375+
corrected_commit_date = commit_graph_data_at(parent->item)->generation;
13761376
if (level == GENERATION_NUMBER_INFINITY ||
1377-
level == GENERATION_NUMBER_ZERO) {
1377+
level == GENERATION_NUMBER_ZERO ||
1378+
corrected_commit_date == GENERATION_NUMBER_INFINITY ||
1379+
corrected_commit_date == GENERATION_NUMBER_ZERO
1380+
) {
13781381
all_parents_computed = 0;
13791382
commit_list_insert(parent->item, &list);
13801383
break;
1381-
} else if (level > max_level) {
1382-
max_level = level;
1384+
} else {
1385+
if (level > max_level)
1386+
max_level = level;
1387+
1388+
if (corrected_commit_date > max_corrected_commit_date)
1389+
max_corrected_commit_date = corrected_commit_date;
13831390
}
13841391
}
13851392

@@ -1389,6 +1396,10 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
13891396
if (max_level > GENERATION_NUMBER_V1_MAX - 1)
13901397
max_level = GENERATION_NUMBER_V1_MAX - 1;
13911398
*topo_level_slab_at(ctx->topo_levels, current) = max_level + 1;
1399+
1400+
if (current->date && current->date > max_corrected_commit_date)
1401+
max_corrected_commit_date = current->date - 1;
1402+
commit_graph_data_at(current)->generation = max_corrected_commit_date + 1;
13921403
}
13931404
}
13941405
}
@@ -2485,17 +2496,9 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
24852496
if (generation_zero == GENERATION_ZERO_EXISTS)
24862497
continue;
24872498

2488-
/*
2489-
* If one of our parents has generation GENERATION_NUMBER_V1_MAX, then
2490-
* our generation is also GENERATION_NUMBER_V1_MAX. Decrement to avoid
2491-
* extra logic in the following condition.
2492-
*/
2493-
if (max_generation == GENERATION_NUMBER_V1_MAX)
2494-
max_generation--;
2495-
24962499
generation = commit_graph_generation(graph_commit);
2497-
if (generation != max_generation + 1)
2498-
graph_report(_("commit-graph generation for commit %s is %u != %u"),
2500+
if (generation < max_generation + 1)
2501+
graph_report(_("commit-graph generation for commit %s is %"PRItime" < %"PRItime),
24992502
oid_to_hex(&cur_oid),
25002503
generation,
25012504
max_generation + 1);

0 commit comments

Comments
 (0)