Re: [PATCH] packfile: skip decompressing and hashing blobs in add_promisor_object()
- From
Jeff King <peff@peff.net>
- Date
- Dec 6, 2025, 01:58 UTC
- Message-ID
- <20251206015830.GA1714099@coredump.intra.peff.net>
- In-Reply-To
- <4bd18399-26b3-44cd-93a7-8d2d32bef709@nvidia.com>
On Fri, Dec 05, 2025 at 01:56:23PM -0800, Aaron Plattner wrote:
Show 28 quoted lines
> > I do wonder how you end up with OBJ_NONE, though. That implies somebody
> > created the "struct object" but without knowing which type it was
> > supposed to be, and then did not follow up by actually parsing it.
>
> If I'm understanding correctly, this loop creates a dummy struct object for
> every object in the promisor packs:
>
> if (revs->exclude_promisor_objects) {
> for_each_packed_object(revs->repo, mark_uninteresting, revs,
> FOR_EACH_OBJECT_PROMISOR_ONLY);
> }
>
> Backtrace for one such object:
>
> #0 create_object
> #1 lookup_unknown_object
> #2 mark_uninteresting
> #3 for_each_object_in_pack
> #4 for_each_packed_object
> #5 prepare_revision_walk
> #6 cmd_rev_list
> #7 run_builtin
> #8 handle_builtin
> #9 cmd_main
> #10 main
>
> Then the is_promisor_object() loop finds these dummy objects when it loops
> over all the objects again.Ah, of course. That makes sense (and I don't think there's any other way to do it, as we need the object struct to store the flags).
And that also explains this bit:
Show 5 quoted lines
> > That's probably immaterial to what parse_object() should be doing, but > > it is certainly a curiosity. And I'm also not sure why I got good > > results from my rev-list invocation, but you did not. Weird. > > Yeah, that's still a mystery.
It's because in the command I used:
git rev-list --objects --exclude-promisor-objects $(perl -e 'print "1" x 40')
we call into is_promisor_object() _before_ we hit that part of prepare_revision_walk() that marks everything uninteresting. In my invocation above, we'd notice the missing object in get_reference() as we try to load the initial tips for the walk, and then check it against is_promisor_object() immediately.
And when I tried something more like your command:
git rev-list --objects --all --exclude-promisor-objects
it did mark them all uninteresting, but because I had no objects that were missing (and not simply marked uninteresting), it never needed to call into is_promisor_object().
So good, mystery resolved.
Show 12 quoted lines
> > 2. You didn't have a commit-graph built. > > This repository came from "scalar clone" and then I created a worktree and > disabled sparse checkout. I didn't do anything special to enable or disable > commit-graph. > > What I do notice is that usually, a `git pull` from the server this > repository is hosted on is fast, but occasionally it hits this pathological > case. I was using git-rev-list as a proxy for what git-pull was getting > stuck on. Is it possible that having a working commit-graph is what avoids > the problem in the first place? I'll admit to not having a great > understanding of how the commit graph is used during a normal pull.
I'd expect scalar to create commit-graphs. We can leave it be, but if you're curious you can double-check that .git/objects/info has either a commit-graph file or a commit-graphs/ directory. If not, then running "git commit-graph write -reachable" should generate one, and you can see if that changes the timings at all.
-Peff