]> git.ipfire.org Git - thirdparty/git.git/commit
builtin/log: prefetch necessary blobs for `git cherry`
authorElijah Newren <newren@gmail.com>
Thu, 14 May 2026 16:25:27 +0000 (16:25 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 14 May 2026 19:24:54 +0000 (04:24 +0900)
commit463c1bfc2b65357569055916e348e1bd9c7a5b25
tree844b98c54035f5329ebd35b9fd059cc526abe767
parentadfb1e4993074fd478c96d3b9da30706e5dd030a
builtin/log: prefetch necessary blobs for `git cherry`

In partial clones, `git cherry` fetches necessary blobs on-demand one
at a time, which can be very slow.  We would like to prefetch all
necessary blobs upfront.  To do so, we need to be able to first figure
out which blobs are needed.

`git cherry` does its work in a two-phase approach: first computing
header-only IDs (based on file paths and modes), then falling back to
full content-based IDs only when header-only IDs collide -- or, more
accurately, whenever the oidhash() of the header-only object_ids
collide.

patch-ids.c handles this by creating an ids->patches hashmap that has
all the data we need, but the problem is that any attempt to query the
hashmap will invoke the patch_id_neq() function on any colliding objects,
which causes the on-demand fetching.

Insert a new prefetch_cherry_blobs() function before checking for
collisions.  Use a temporary replacement on the ids->patches.cmpfn
in order to enumerate the blobs that would be needed without yet
fetching them, and then fetch them all at once, then restore the old
ids->patches.cmpfn.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/log.c
t/t3500-cherry.sh