Skip to content

commit-graph: use timestamp_t for max parent generation accumulator#2148

Open
newren wants to merge 1 commit into
gitgitgadget:masterfrom
newren:commit-graph-fix-ccd-uint32-truncation
Open

commit-graph: use timestamp_t for max parent generation accumulator#2148
newren wants to merge 1 commit into
gitgitgadget:masterfrom
newren:commit-graph-fix-ccd-uint32-truncation

Conversation

@newren

@newren newren commented Jun 12, 2026

Copy link
Copy Markdown

We found a few repositories in the wild with commits whose authors were apparently on a computer in the year 2120 when they recorded their commits. Apparently, in a century from now, some folks are going to have a really weird timezone as well (-13068837), though the timezone doesn't factor into this patch at all.

@newren newren force-pushed the commit-graph-fix-ccd-uint32-truncation branch 2 times, most recently from d944794 to bdd1ae5 Compare June 12, 2026 20:31
compute_reachable_generation_numbers() computes each commit's
generation as

    max(c->date, max(parent.generation)) + 1

by walking its parents and accumulating their generations into a
local

    uint32_t max_gen = 0;

while info->get_generation() returns timestamp_t and
compute_generation_from_max() already takes its max_gen parameter
as timestamp_t.  For v1 (topological levels) the narrowing is
harmless because GENERATION_NUMBER_V1_MAX is less than 2^30, but
for v2 (corrected committer dates) it silently truncates any
parent generation that does not fit in 32 bits, i.e. any parent
whose committer timestamp is at or beyond 2106-02-07 UTC
(>= 2^32).

The truncated max then causes child commits to end up with a
corrected committer date that matches the parent's instead of being
at least 1 higher.  The bad value gets written into the commit-graph
and causes problems later, and can be noticed by running `git
commit-graph verify`.

Widen the accumulator to timestamp_t.

This is solely an in-memory arithmetic fix with no on-disk format
change: the on-disk format already encodes timestamp_t values and
existing readers handle them unchanged.  This merely allows the code to
compute the correct value to write to disk.

The narrowing was introduced in 80c928d (commit-graph:
simplify compute_generation_numbers(), 2023-03-20), which rewired
v2 to use the shared compute_reachable_generation_numbers()
helper; the helper's local accumulator had been declared uint32_t
in the immediately preceding 368d19b (commit-graph: refactor
compute_topological_levels(), 2023-03-20) when only v1 was using
it, where it was harmless.

Add a new test with a future-dated parent and a present-day child;
without the above fix, `git commit-graph verify` reports the
descendant's stored generation as below parent + 1.

Signed-off-by: Elijah Newren <newren@gmail.com>
@newren newren force-pushed the commit-graph-fix-ccd-uint32-truncation branch from bdd1ae5 to 83f51ca Compare June 12, 2026 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant