From 5413c7aeadb7cb18a6d51dae0bc313f2e129a337 Mon Sep 17 00:00:00 2001 From: Alberto Cortés Date: Tue, 2 Aug 2016 10:58:49 +0200 Subject: Repository head (#61) * add Repository.Head() tests * add head support for remote repos and more tests * add head support for local repos * clean code * remove dead code --- storage/seekable/internal/gitdir/gitdir.go | 2 +- storage/seekable/storage.go | 46 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) (limited to 'storage') diff --git a/storage/seekable/internal/gitdir/gitdir.go b/storage/seekable/internal/gitdir/gitdir.go index bfdf030..d3149ee 100644 --- a/storage/seekable/internal/gitdir/gitdir.go +++ b/storage/seekable/internal/gitdir/gitdir.go @@ -126,7 +126,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 +} -- cgit