aboutsummaryrefslogtreecommitdiffstats
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/seekable/internal/gitdir/gitdir.go5
-rw-r--r--storage/seekable/storage.go46
2 files changed, 50 insertions, 1 deletions
diff --git a/storage/seekable/internal/gitdir/gitdir.go b/storage/seekable/internal/gitdir/gitdir.go
index bfdf030..eea980b 100644
--- a/storage/seekable/internal/gitdir/gitdir.go
+++ b/storage/seekable/internal/gitdir/gitdir.go
@@ -25,6 +25,9 @@ var (
// ErrPackfileNotFound is returned by Packfile when the packfile is not found
// on the repository.
ErrPackfileNotFound = errors.New("packfile not found")
+ // ErrHeadfileNotFound is returned by Headfile when the HEAD file is not found
+ // on the repository.
+ ErrHeadfileNotFound = errors.New("headfile not found")
)
// The GitDir type represents a local git repository on disk. This
@@ -126,7 +129,7 @@ func (d *GitDir) Packfile() (fs.FS, string, error) {
return nil, "", ErrPackfileNotFound
}
-// Packfile returns the path of the idx file (really, it returns the
+// Idxfile returns the path of the idx file (really, it returns the
// path of the first file in the "objects/pack/" directory with an
// ".idx" extension.
func (d *GitDir) Idxfile() (fs.FS, string, error) {
diff --git a/storage/seekable/storage.go b/storage/seekable/storage.go
index 8d75700..db436c8 100644
--- a/storage/seekable/storage.go
+++ b/storage/seekable/storage.go
@@ -3,6 +3,7 @@ package seekable
import (
"fmt"
"os"
+ "strings"
"gopkg.in/src-d/go-git.v3/core"
"gopkg.in/src-d/go-git.v3/formats/packfile"
@@ -150,3 +151,48 @@ func (s *ObjectStorage) Iter(t core.ObjectType) (core.ObjectIter, error) {
return core.NewObjectSliceIter(objects), nil
}
+
+const (
+ headErrPrefix = "cannot get HEAD reference:"
+ symrefCapability = "symref"
+ headRefPrefix = "HEAD:"
+)
+
+// Head returns the hash of the HEAD reference
+func (s *ObjectStorage) Head() (core.Hash, error) {
+ cap, err := s.dir.Capabilities()
+ if err != nil {
+ return core.ZeroHash, fmt.Errorf("%s %s", headErrPrefix, err)
+ }
+
+ ok := cap.Supports(symrefCapability)
+ if !ok {
+ return core.ZeroHash,
+ fmt.Errorf("%s symref capability not supported", headErrPrefix)
+ }
+
+ symrefs := cap.Get(symrefCapability)
+ var headRef string
+ for _, ref := range symrefs.Values {
+ if strings.HasPrefix(ref, headRefPrefix) {
+ headRef = strings.TrimPrefix(ref, headRefPrefix)
+ }
+ }
+ if headRef == "" {
+ return core.ZeroHash, fmt.Errorf("%s HEAD reference not found",
+ headErrPrefix)
+ }
+
+ refs, err := s.dir.Refs()
+ if err != nil {
+ return core.ZeroHash, fmt.Errorf("%s %s", headErrPrefix, err)
+ }
+
+ head, ok := refs[headRef]
+ if !ok {
+ return core.ZeroHash, fmt.Errorf("%s reference %q not found",
+ headErrPrefix, headRef)
+ }
+
+ return head, nil
+}