diff options
author | David Symonds <dsymonds@golang.org> | 2020-07-15 13:52:04 +1000 |
---|---|---|
committer | David Symonds <dsymonds@golang.org> | 2020-07-16 12:53:37 +1000 |
commit | e28d9c90aad624596d20d1a59c8371d81b69190b (patch) | |
tree | 5785565db48069ff8f173b9dddcbb1b4c1f7e8ff /storage/filesystem/object.go | |
parent | 41758ec4b81c557092d7566c3eed46f89c1ec3cc (diff) | |
download | go-git-e28d9c90aad624596d20d1a59c8371d81b69190b.tar.gz |
Support partial hashes in Repository.ResolveRevision.
Like `git rev-parse <prefix>`, this enumerates the hashes of objects
with the given prefix and adds them to the list of candidates for
resolution.
This has an exhaustive slow path, which requires enumerating all objects
and filtering each one, but also a couple of fast paths for common
cases. There's room for future work to make this faster; TODOs have been
left for that.
Fixes #135.
Diffstat (limited to 'storage/filesystem/object.go')
-rw-r--r-- | storage/filesystem/object.go | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/storage/filesystem/object.go b/storage/filesystem/object.go index 7437174..0c25dad 100644 --- a/storage/filesystem/object.go +++ b/storage/filesystem/object.go @@ -1,6 +1,7 @@ package filesystem import ( + "bytes" "io" "os" "time" @@ -518,6 +519,36 @@ func (s *ObjectStorage) findObjectInPackfile(h plumbing.Hash) (plumbing.Hash, pl return plumbing.ZeroHash, plumbing.ZeroHash, -1 } +func (s *ObjectStorage) HashesWithPrefix(prefix []byte) ([]plumbing.Hash, error) { + hashes, err := s.dir.ObjectsWithPrefix(prefix) + if err != nil { + return nil, err + } + + // TODO: This could be faster with some idxfile changes, + // or diving into the packfile. + for _, index := range s.index { + ei, err := index.Entries() + if err != nil { + return nil, err + } + for { + e, err := ei.Next() + if err == io.EOF { + break + } else if err != nil { + return nil, err + } + if bytes.HasPrefix(e.Hash[:], prefix) { + hashes = append(hashes, e.Hash) + } + } + ei.Close() + } + + return hashes, nil +} + // IterEncodedObjects returns an iterator for all the objects in the packfile // with the given type. func (s *ObjectStorage) IterEncodedObjects(t plumbing.ObjectType) (storer.EncodedObjectIter, error) { |