From: Justin Tobler Date: Wed, 18 Feb 2026 19:34:01 GMT Subject: Re: [PATCH 3/3] commit: use commit graph in `lookup_commit_reference_gently()` Message-ID: In-Reply-To: <20260216-b4-pks-receive-pack-optimize-shallow-v1-3-e98886daff2b@pks.im> On 26/02/16 04:38PM, Patrick Steinhardt wrote: > In the preceding commit we refactored `lookup_commit_reference_gently()` > so that it doesn't parse non-commit objects anymore. This has led to a > speedup when git-receive-pack(1) accepts a shallow push into a repo > with lots of refs that point to blobs or trees. > > But while this case is now faster, we still have the issue that > accepting pushes with lots of "normal" refs that point to commits are > still slow. This is mostly because we look up the commits via the object > database, and that is rather costly. > > Adapt the code to use `repo_parse_commit_gently()` instead of > `parse_object()` to parse the resulting commit object. This function > knows to use the commit-graph to fill in the object, which is way more > cost efficient. Makes sense. > This leads to another significant speedup when accepting shallow pushes. > The following benchmark pushes a single objects from a shallow clone > into a repository with 600,000 references that all point to commits: > > Benchmark 1: git-receive-pack (rev = HEAD~) > Time (mean ± σ): 9.179 s ± 0.031 s [User: 8.858 s, System: 0.528 s] > Range (min … max): 9.154 s … 9.213 s 3 runs > > Benchmark 2: git-receive-pack (rev = HEAD) > Time (mean ± σ): 2.337 s ± 0.032 s [User: 2.331 s, System: 0.234 s] > Range (min … max): 2.308 s … 2.371 s 3 runs > > Summary > git-receive-pack . 3.93 ± 0.05 times faster than git-receive-pack (rev = HEAD~) > > Also, this again leads to a significant reduction in memory allocations. > Before this change: > > HEAP SUMMARY: > in use at exit: 17,524,978 bytes in 22,393 blocks > total heap usage: 33,313 allocs, 10,920 frees, 407,774,251 bytes allocated > > And after this change: > > HEAP SUMMARY: > in use at exit: 11,534,036 bytes in 12,406 blocks > total heap usage: 13,284 allocs, 878 frees, 15,521,451 bytes allocated Very nice :) > Signed-off-by: Patrick Steinhardt > --- > commit.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/commit.c b/commit.c > index b7c4ec2eb5..014f74822c 100644 > --- a/commit.c > +++ b/commit.c > @@ -45,7 +45,7 @@ struct commit *lookup_commit_reference_gently(struct repository *r, > { > const struct object_id *maybe_peeled; > struct object_id peeled_oid; > - struct object *object; > + struct commit *commit; > enum object_type type; > > switch (peel_object_ext(r, oid, &peeled_oid, 0, &type)) { > @@ -67,11 +67,11 @@ struct commit *lookup_commit_reference_gently(struct repository *r, > return NULL; > } > > - object = parse_object(r, maybe_peeled); > - if (!object) > + commit = lookup_commit(r, maybe_peeled); > + if (!commit || repo_parse_commit_gently(r, commit, quiet) < 0) > return NULL; Now it is possible to use the commit-graph to parse the commit. > > - return object_as_type(object, OBJ_COMMIT, quiet); > + return commit; > } > > struct commit *lookup_commit_reference(struct repository *r, const struct object_id *oid) Thanks Patrick. This looks good to me. -Justin