Subject: Re: [GSoC][RFC PATCH 0/2] Add refs list subcommand

From: Patrick Steinhardt <[email-masked]>
Date: Wed, 9 Jul 2025 15:36:08 +0200

On Mon, Jun 30, 2025 at 01:10:36PM -0700, Junio C Hamano wrote:
> Meet Soni <[email-masked]> writes:
> 
> > To clarify, I don't have specific options or improvements in mind right now.
> > The idea behind mentioning them was to acknowledge that having a consolidated
> > interface like git refs might open the door to such discussions.
> 
> One complaint we heard a lot about Git in the past (I do not know if
> people got used to and learned to live with, or they are still
> complaining about the same these days) was that there were always
> multiple ways to do related things slightly differently.
> 
> The machinery of for-each-ref is shared by branch and tag to give
> them feature-parity.  Adding yet another command that behaves
> slightly differently, with the intention to make it diverge even
> more in the future, feels going backwards.

That's fair. I do think that the common infrastructure should be shared
indeed, and that includes the options. So the most important benefit of
the new subcommand would be an improvement to discoverability.

But there is one default in git-for-each-ref(1) that has been biting us
multiple times at GitLab already, namely the default format. In
git-for-each-ref(1) it is:

    %(objectname) %(objecttype)\t%(refname)

The problem with this format is `%(objecttype)` -- it requires us to not
only read refs from the reference database, but also resolve the object
via the ODB so that we can figure out its type. And that can be a huge
slowdown in large repositories. Take e.g. the Chromium repository:

    Benchmark 1: git for-each-ref
      Time (mean ± σ):     148.9 ms ±   1.0 ms    [User: 80.7 ms, System: 67.2 ms]
      Range (min … max):   147.2 ms … 154.2 ms    100 runs

    Benchmark 2: git for-each-ref --format="%(objectname) %(refname)"
      Time (mean ± σ):      22.4 ms ±   0.3 ms    [User: 21.4 ms, System: 1.0 ms]
      Range (min … max):    22.0 ms …  24.0 ms    100 runs

    Summary
      git for-each-ref --format="%(objectname) %(refname)" ran
        6.65 ± 0.09 times faster than git for-each-ref

So from my point of view, this is a thing we should consider changing in
the new subcommand. For all the other options I agree, we should have
common infra and thus common options.

Patrick