@@ -1319,6 +1319,31 @@ static int write_graph_chunk_data(struct hashfile *f,
13191319 return 0 ;
13201320}
13211321
1322+ /*
1323+ * Compute the generation offset between the commit date and its generation.
1324+ * This is what's ultimately stored as generation number in the commit graph.
1325+ *
1326+ * Note that the computation of the commit date is more involved than you might
1327+ * think. Instead of using the full commit date, we're in fact masking bits so
1328+ * that only the 34 lowest bits are considered. This results from the fact that
1329+ * commit graphs themselves only ever store 34 bits of the commit date
1330+ * themselves.
1331+ *
1332+ * This means that if we have a commit date that exceeds 34 bits we'll end up
1333+ * in situations where depending on whether the commit has been parsed from the
1334+ * object database or the commit graph we'll have different dates, where the
1335+ * ones parsed from the object database would have full 64 bit precision.
1336+ *
1337+ * But ultimately, we only ever want the offset to be relative to what we
1338+ * actually end up storing on disk, and hence we have to mask all the other
1339+ * bits.
1340+ */
1341+ static timestamp_t compute_generation_offset (struct commit * c )
1342+ {
1343+ timestamp_t masked_date = c -> date & (((timestamp_t ) 1 << 34 ) - 1 );
1344+ return commit_graph_data_at (c )-> generation - masked_date ;
1345+ }
1346+
13221347static int write_graph_chunk_generation_data (struct hashfile * f ,
13231348 void * data )
13241349{
@@ -1329,7 +1354,7 @@ static int write_graph_chunk_generation_data(struct hashfile *f,
13291354 struct commit * c = ctx -> commits .items [i ];
13301355 timestamp_t offset ;
13311356 repo_parse_commit (ctx -> r , c );
1332- offset = commit_graph_data_at (c )-> generation - c -> date ;
1357+ offset = compute_generation_offset (c );
13331358 display_progress (ctx -> progress , ++ ctx -> progress_cnt );
13341359
13351360 if (offset > GENERATION_NUMBER_V2_OFFSET_MAX ) {
@@ -1350,7 +1375,7 @@ static int write_graph_chunk_generation_data_overflow(struct hashfile *f,
13501375 int i ;
13511376 for (i = 0 ; i < ctx -> commits .nr ; i ++ ) {
13521377 struct commit * c = ctx -> commits .items [i ];
1353- timestamp_t offset = commit_graph_data_at (c )-> generation - c -> date ;
1378+ timestamp_t offset = compute_generation_offset (c );
13541379 display_progress (ctx -> progress , ++ ctx -> progress_cnt );
13551380
13561381 if (offset > GENERATION_NUMBER_V2_OFFSET_MAX ) {
@@ -1741,7 +1766,7 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
17411766
17421767 for (i = 0 ; i < ctx -> commits .nr ; i ++ ) {
17431768 struct commit * c = ctx -> commits .items [i ];
1744- timestamp_t offset = commit_graph_data_at (c )-> generation - c -> date ;
1769+ timestamp_t offset = compute_generation_offset (c );
17451770 if (offset > GENERATION_NUMBER_V2_OFFSET_MAX )
17461771 ctx -> num_generation_data_overflows ++ ;
17471772 }
0 commit comments