fetch: speed up lookup of want refs via commit-graph
commitfe7df03a9a2fa434ebce38b2cd5e6da42f8b2692
authorPatrick Steinhardt <ps@pks.im>
Wed, 1 Sep 2021 13:09:41 +0000 (1 15:09 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 1 Sep 2021 19:43:56 +0000 (1 12:43 -0700)
tree94581fcabcc5dfcaf22782f984d4950ed56c06b7
parent6c40894d2466d4e7fddc047a05116aa9d14712ee
fetch: speed up lookup of want refs via commit-graph

When updating our local refs based on the refs fetched from the remote,
we need to iterate through all requested refs and load their respective
commits such that we can determine whether they need to be appended to
FETCH_HEAD or not. In cases where we're fetching from a remote with
exceedingly many refs, resolving these refs can be quite expensive given
that we repeatedly need to unpack object headers for each of the
referenced objects.

Speed this up by opportunistically trying to resolve object IDs via the
commit graph. We only do so for any refs which are not in "refs/tags":
more likely than not, these are going to be a commit anyway, and this
lets us avoid having to unpack object headers completely in case the
object is a commit that is part of the commit-graph. This significantly
speeds up mirror-fetches in a real-world repository with
2.3M refs:

    Benchmark #1: HEAD~: git-fetch
      Time (mean ± σ):     56.482 s ±  0.384 s    [User: 53.340 s, System: 5.365 s]
      Range (min … max):   56.050 s … 57.045 s    5 runs

    Benchmark #2: HEAD: git-fetch
      Time (mean ± σ):     33.727 s ±  0.170 s    [User: 30.252 s, System: 5.194 s]
      Range (min … max):   33.452 s … 33.871 s    5 runs

    Summary
      'HEAD: git-fetch' ran
        1.67 ± 0.01 times faster than 'HEAD~: git-fetch'

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/fetch.c