Re: Fully peel tags via for-each-ref?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Aug 19, 2019 at 10:50:24PM -0700, Junio C Hamano wrote:

> Bryan Turner <bturner@xxxxxxxxxxxxx> writes:
> 
> > Is there any way, with "git for-each-ref", to output the "fully"
> > peeled SHA of a tag's ultimate target, regardless of how many layers
> > must be traversed?
> 
> I do not think I wrote it to allow different degree of peeling, not
> because I wanted to explicitly forbid a use case for tags that tag
> another tag, but simply because I didn't think of anybody using it
> and didn't see need to support such tags.
> 
> If %(*<stuff>) does not peel fully (I do not recall what I did
> offhand), because all other things in Git (like $X~0, $X^{tree},
> etc.) fully peel the outer object until they get to what they want,
> it may even be OK to declare it a bug and "fix" the notation to
> fully peel tags.  I dunno.

Yeah, my first thought on reading Bryan's email was that this is so
inconsistent with the rest of Git as to be considered a bug.

There's this gem in ref-filter.c, which blames back to your 9f613ddd21
(Add git-for-each-ref: helper for language bindings, 2006-09-15):

          /*
           * NEEDSWORK: This derefs tag only once, which
           * is good to deal with chains of trust, but
           * is not consistent with what deref_tag() does
           * which peels the onion to the core.
           */
          return get_object(ref, 1, &obj, &oi_deref, err);

Which isn't to say it isn't useful to be able to do a single-layer peel,
but I can't think of another part of the system which does so (unless
you've asked to peel to a specific type, of course). I'm thinking
especially of the way upload-pack does its advertisement, with two
interesting implications:

  1. We store full peels in the packed-refs file[1], so we can show them
     in the advertisement without having to access the object. Doing:

       git upload-pack . </dev/null >/dev/null

     is much cheaper than:

       git for-each-ref \
         --format='%(objectname) %(refname)%0a%(*objectname) %(refname)^{}' \
	 >/dev/null

  2. When we switched for_each_alternate_ref to using peeled values, we
     stopped advertising peeled values for .push haves entirely. There's
     some discussion in a10a17877b (for_each_alternate_ref: replace
     transport code with for-each-ref, 2017-02-08), but if we _did_ want
     to show them, we'd probably want the fully peeled value to match
     the rest of the advertisement.

Given that it's not how the rest of Git works, I'd be surprised for
anybody to be relying on the shallow-peeling behavior of for-each-ref.
But if we did want to retain it, it might be worth adding a separate
syntax for a full peel. "%(**objectname)" or something?

-Peff

[1] Storing peeled values in the packed-refs file is itself a pretty
    horrible hack. It's really a property of the object itself, and
    we're just piggy-backing on the ref storage to make this cached
    metadata easily accessible. It would be more appropriate in an
    object metadata storage format similar to the commit-graph file.
    And then of course we could store both full or partial peels,
    depending on the format.



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux