ref-filter.c: use peeled tag for '*' format fields
In most builtins ('rev-parse <revision>^{}', 'show-ref --dereference'),
"dereferencing" a tag refers to a recursive peel of the tag object. Unlike
these cases, the dereferencing prefix ('*') in 'for-each-ref' format
specifiers triggers only a single, non-recursive dereference of a given tag
object. For most annotated tags, a single dereference is all that is needed
to access the tag's associated commit or tree; "recursive" and
"non-recursive" dereferencing are functionally equivalent in these cases.
However, nested tags (annotated tags whose target is another annotated tag)
dereferenced once return another tag, where a recursive dereference would
return the commit or tree.
Currently, if a user wants to filter & format refs and include information
about a recursively-dereferenced tag, they can do so with something like
'cat-file --batch-check':
git for-each-ref --format="%(objectname)^{} %(refname)" <pattern> |
git cat-file --batch-check="%(objectname) %(rest)"
But the combination of commands is inefficient. So, to improve the
performance of this use case and align the defererencing behavior of
'for-each-ref' with that of other commands, update the ref formatting code
to use the peeled tag (from 'peel_iterated_oid()') to populate '*' fields
rather than the tag's immediate target object (from 'get_tagged_oid()').
Additionally, add a test to 't6300-for-each-ref' to verify new nested tag
behavior and update 't6302-for-each-ref-filter.sh' to print the correct
value for nested dereferenced fields.
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
d1dfe6e936
commit
188782ecb1
13
ref-filter.c
13
ref-filter.c
@ -2424,17 +2424,12 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If it is a tag object, see if we use a value that derefs
|
||||
* the object, and if we do grab the object it refers to.
|
||||
* If it is a tag object, see if we use the peeled value. If we do,
|
||||
* grab the peeled OID.
|
||||
*/
|
||||
oi_deref.oid = *get_tagged_oid((struct tag *)obj);
|
||||
if (need_tagged && peel_iterated_oid(&obj->oid, &oi_deref.oid))
|
||||
die("bad tag");
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user