From 6cdf75c5a9e1f660aa2a86938be680c5db07ffd2 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sat, 21 Feb 2026 11:33:40 +0800 Subject: refstore: Add ref shortening --- refstore/shorten.go | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 refstore/shorten.go (limited to 'refstore/shorten.go') diff --git a/refstore/shorten.go b/refstore/shorten.go new file mode 100644 index 00000000..26fa82c0 --- /dev/null +++ b/refstore/shorten.go @@ -0,0 +1,74 @@ +package refstore + +import "strings" + +type shortenRule struct { + prefix string + suffix string +} + +var shortenRules = [...]shortenRule{ + {prefix: "", suffix: ""}, + {prefix: "refs/", suffix: ""}, + {prefix: "refs/tags/", suffix: ""}, + {prefix: "refs/heads/", suffix: ""}, + {prefix: "refs/remotes/", suffix: ""}, + {prefix: "refs/remotes/", suffix: "/HEAD"}, +} + +func (rule shortenRule) match(name string) (string, bool) { + if !strings.HasPrefix(name, rule.prefix) { + return "", false + } + if !strings.HasSuffix(name, rule.suffix) { + return "", false + } + short := strings.TrimPrefix(name, rule.prefix) + short = strings.TrimSuffix(short, rule.suffix) + if short == "" { + return "", false + } + if rule.prefix+short+rule.suffix != name { + return "", false + } + return short, true +} + +func (rule shortenRule) render(short string) string { + return rule.prefix + short + rule.suffix +} + +// ShortenName returns the shortest unambiguous shorthand for name among all. +// +// all must contain full reference names visible to the shortening scope. +func ShortenName(name string, all []string) string { + names := make(map[string]struct{}, len(all)) + for _, full := range all { + if full == "" { + continue + } + names[full] = struct{}{} + } + + for i := len(shortenRules) - 1; i > 0; i-- { + short, ok := shortenRules[i].match(name) + if !ok { + continue + } + ambiguous := false + for j := range shortenRules { + if j == i { + continue + } + full := shortenRules[j].render(short) + if _, found := names[full]; found { + ambiguous = true + break + } + } + if !ambiguous { + return short + } + } + return name +} -- cgit v1.3.1-10-gc9f91