diff options
context:
space:
mode:
Diffstat (limited to 'source/ui-shared.c')
-rw-r--r--source/ui-shared.c43
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);
}