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/loose/loose_test.go | 32 ++++++++++++++++++++++++++++++++ refstore/loose/shorten.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 refstore/loose/shorten.go (limited to 'refstore/loose') diff --git a/refstore/loose/loose_test.go b/refstore/loose/loose_test.go index b56e40ac..63898721 100644 --- a/refstore/loose/loose_test.go +++ b/refstore/loose/loose_test.go @@ -147,3 +147,35 @@ func TestLooseMalformedDetachedRef(t *testing.T) { } }) } + +func TestLooseShorten(t *testing.T) { + testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { + testRepo := testgit.NewBareRepo(t, algo) + _, _, commitID := testRepo.MakeCommit(t, "shorten refs commit") + testRepo.UpdateRef(t, "refs/heads/main", commitID) + testRepo.UpdateRef(t, "refs/tags/main", commitID) + testRepo.UpdateRef(t, "refs/remotes/origin/main", commitID) + + store := openLooseStore(t, testRepo.Dir(), algo) + + shortHead, err := store.Shorten("refs/heads/main") + if err != nil { + t.Fatalf("Shorten(head): %v", err) + } + if shortHead != "heads/main" { + t.Fatalf("Shorten(refs/heads/main) = %q, want %q", shortHead, "heads/main") + } + + shortRemote, err := store.Shorten("refs/remotes/origin/main") + if err != nil { + t.Fatalf("Shorten(remote): %v", err) + } + if shortRemote != "origin/main" { + t.Fatalf("Shorten(remote) = %q, want %q", shortRemote, "origin/main") + } + + if _, err := store.Shorten("refs/heads/does-not-exist"); !errors.Is(err, refstore.ErrReferenceNotFound) { + t.Fatalf("Shorten(not-found) error = %v", err) + } + }) +} diff --git a/refstore/loose/shorten.go b/refstore/loose/shorten.go new file mode 100644 index 00000000..17a60def --- /dev/null +++ b/refstore/loose/shorten.go @@ -0,0 +1,29 @@ +package loose + +import ( + "codeberg.org/lindenii/furgit/refstore" +) + +// Shorten returns the shortest unambiguous shorthand for a loose ref name. +func (store *Store) Shorten(name string) (string, error) { + refs, err := store.List("") + if err != nil { + return "", err + } + names := make([]string, 0, len(refs)) + found := false + for _, entry := range refs { + if entry == nil { + continue + } + full := entry.Name() + names = append(names, full) + if full == name { + found = true + } + } + if !found { + return "", refstore.ErrReferenceNotFound + } + return refstore.ShortenName(name, names), nil +} -- cgit v1.3.1-10-gc9f91