diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Settle the snapshot v-prefix from the tag list
`compose_snapshot_prefix` dropped the leading v of a tag only when just
one of the names 1.2, v1.2 and V1.2 resolved as a tag, so that the
shorter snapshot name could always be traced back to one tag. Those
probes went through ref lookups, and on a case-insensitive filesystem
a lookup for V1.2 finds the loose file of v1.2, so every freshly made
tag counted as ambiguous and kept its v. Once git packed the refs the
lookups became exact and the same tag quietly changed its snapshot
names.
The claimants on a stripped name are now counted over the tag list
itself with exact string comparison, so the answer no longer depends
on how a ref is stored or on the filesystem underneath. Two tags that
really differ only by the letter's case still both keep it.
Diffstat (limited to 'source/ui-shared.c')
| -rw-r--r-- | source/ui-shared.c | 43 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 file changed, 35 insertions, 8 deletions
diff --git a/source/ui-shared.c b/source/ui-shared.c index 58e7f03..2f0843c 100644 --- a/source/ui-shared.c +++ b/source/ui-shared.c @@ -1741,20 +1741,47 @@ void cgit_print_filemode(unsigned short mode) html_fileperm(mode); } -static void compose_snapshot_prefix(struct strbuf *filename, const char *base, const char *ref) +/* + * One tag's claim on a snapshot stem, the stem being the tag name with any + * leading v or V removed. Claims are counted over the tag list itself rather + * than by looking refs up by name, because a loose ref lookup on a + * case-insensitive filesystem finds v1.2 when asked for V1.2 and would call + * every tag still stored loose ambiguous. + */ +struct snapshot_stem { + const char *tag; + const char *stem; + int claimants; + int is_tag; +}; + +static int count_stem_claimants(const struct reference *ref, void *data) { - struct object_id oid; + struct snapshot_stem *probe = data; + const char *name = ref->name; + if (!strcmp(name, probe->tag)) + probe->is_tag = 1; + if (name[0] == 'v' || name[0] == 'V') + name++; + if (!strcmp(name, probe->stem)) + probe->claimants++; + return 0; +} + +static void compose_snapshot_prefix(struct strbuf *filename, const char *base, const char *ref) +{ // A tag named v1.2 or V1.2 gives its snapshot the prettier name 1.2, // but only where dropping the letter cannot land two different tags on // one name, so that a snapshot can still be traced back to the tag it // was made from. - if (repo_get_oid(the_repository, cgit_fmt("refs/tags/%s", ref), &oid) == 0 && - (ref[0] == 'v' || ref[0] == 'V') && isdigit((unsigned char)ref[1]) && - ((repo_get_oid(the_repository, cgit_fmt("refs/tags/%s", ref + 1), &oid) == 0) + - (repo_get_oid(the_repository, cgit_fmt("refs/tags/v%s", ref + 1), &oid) == 0) + - (repo_get_oid(the_repository, cgit_fmt("refs/tags/V%s", ref + 1), &oid) == 0) == 1)) - ref++; + if ((ref[0] == 'v' || ref[0] == 'V') && isdigit((unsigned char)ref[1])) { + struct snapshot_stem probe = { .tag = ref, .stem = ref + 1 }; + + refs_for_each_tag_ref(get_main_ref_store(the_repository), count_stem_claimants, &probe); + if (probe.is_tag && probe.claimants == 1) + ref++; + } strbuf_addf(filename, "%s-%s", base, ref); } |
