aboutsummaryrefslogtreecommitdiff
path: root/refstore/loose
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-02-21 11:33:40 +0800
committerGravatar Runxi Yu2026-02-21 11:33:40 +0800
commit6cdf75c5a9e1f660aa2a86938be680c5db07ffd2 (patch)
treef16f22cc51930e97eaeb73e1e436d8a4c331fabf /refstore/loose
parentrefstore/loose: Add loose refs implementation (diff)
signatureNo signature
refstore: Add ref shortening
Diffstat (limited to 'refstore/loose')
-rw-r--r--refstore/loose/loose_test.go32
-rw-r--r--refstore/loose/shorten.go29
2 files changed, 61 insertions, 0 deletions
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
+}