On Fri, 22 August 2008, Giuseppe Bilotta wrote:
On Fri, Aug 22, 2008 at 10:49 AM, Jakub Narebski [off-list ref] wrote:
quoted
What format_ref_marker() uses is not exactly 'type' of reference, but
more 'kind of' reference. It is based on reference namespace, not
on type of object the reference is at (points to). So code based
on this info (like your v3 patch) would fail on lightweight tag, i.e.
if there is ref in 'refs/tags' namespace which points directly to commit,
and not to tag object.
But 'git show-ref --dereference' _has_ information about whether
given reference points directly or indirectly to given object
($refs->{$id}), but currently we neither save it, nor use it.
For example we can have:
781c1834f5419bdf81bb7f3750170ccd6b809174 refs/heads/maint
...
124c62e8781a8f03ee0256bee78f7b392e3920af refs/stash
...
89e6fcde639d65823e8113c307067441701ac74f refs/tags/Attic/gitweb/parse_rev_list
b69a41a384d19fe253b9f4f34c9019ad96ca571d refs/tags/Attic/gitweb/patchset_body
781c1834f5419bdf81bb7f3750170ccd6b809174 refs/tags/TEMP
...
07cca3b30ee2b5d060e44e5b18d7c22929c63d1a refs/tags/v1.5.6.5
781c1834f5419bdf81bb7f3750170ccd6b809174 refs/tags/v1.5.6.5^{}
Now in this example we have three refs pointing to commit object
781c1834: refs/heads/maint, refs/tags/TEMP and refs/tags/v1.5.6.5.
From those only refs/tags/v1.5.6.5 is (via) tag, even though TEMP
is in tags namespace. Currently git_get_references() strips '^{}'
indirect reference marker from the output (from refname), and doesn't
make use of it. One solution would be to not stip it in
git_get_references(), but leave it, and strip it and make use of
it (if ref ends with '^{}' it must be tag object) in format_ref_marker().
Ah, I see what you mean. If I understand correctly, this particular
situation is only a problem with tags, as they can be either
lighweight tags (that reference a commit) or actual tag objects (that
are indirect references to commits and direct references to
themselves), whereas everything else is just direct references to
object.
Yes, properly managed git repository should have refs pointing to
tag objects only in 'refs/tags' (tags) namespace.
Handling this requires a couple of extra info to be carried
over in $refs, so I guess I'll have to experiment with it a little
since it would require a more extensive change than I originally
planned.
This "couple of extra info" could be just '^{}' suffix. So I don't
think it would be very complicated.
You could simply do not strip '^{}' suffix in git_get_references()
subroutine (so for example $refs->{$id} could be "tags/v1.6.0^{}",
and not simply "tags/v1.6.0" when $id is sha-1 of a _commit_ indirectly
referenced by v1.6.0, i.e. referenced by v1.6.0 _tag_), and strip
it and make use of it in format_ref_marker():
if ($ref =~ s/\^\{\}$//) {
# $ref is a tag
} else {
# $ref points directly to object
}
HTH.
P.S. I have re-added git mailing list to Cc:.
--
Jakub Narebski
Poland