Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ func (c *Commit) File(path string) (file *File, err error) {

// Decode transform an core.Object into a Blob struct
func (c *Commit) Decode(o core.Object) error {
if o.Type() != core.CommitObject {
return ErrUnsupportedObject
}

c.Hash = o.Hash()
r := bufio.NewReader(o.Reader())

Expand Down
3 changes: 3 additions & 0 deletions core/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import (
// Hash SHA1 hased content
type Hash [20]byte

// ZeroHash is Hash with value zero
var ZeroHash Hash

// ComputeHash compute the hash for a given ObjectType and content
func ComputeHash(t ObjectType, content []byte) Hash {
h := t.Bytes()
Expand Down
87 changes: 1 addition & 86 deletions core/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
package core

import (
"bytes"
"errors"
"io"
)
Expand All @@ -13,11 +12,11 @@ var (

// Object is a generic representation of any git object
type Object interface {
Hash() Hash
Type() ObjectType
SetType(ObjectType)
Size() int64
SetSize(int64)
Hash() Hash
Reader() io.Reader
Writer() io.Writer
}
Expand Down Expand Up @@ -147,87 +146,3 @@ func (iter *ObjectSliceIter) Next() (Object, error) {
func (iter *ObjectSliceIter) Close() {
iter.pos = len(iter.series)
}

type RAWObject struct {
b []byte
t ObjectType
s int64
}

func (o *RAWObject) Type() ObjectType { return o.t }
func (o *RAWObject) SetType(t ObjectType) { o.t = t }
func (o *RAWObject) Size() int64 { return o.s }
func (o *RAWObject) SetSize(s int64) { o.s = s }
func (o *RAWObject) Reader() io.Reader { return bytes.NewBuffer(o.b) }
func (o *RAWObject) Hash() Hash { return ComputeHash(o.t, o.b) }
func (o *RAWObject) Writer() io.Writer { return o }
func (o *RAWObject) Write(p []byte) (n int, err error) {
o.b = append(o.b, p...)
return len(p), nil
}

type RAWObjectStorage struct {
Objects map[Hash]Object
Commits map[Hash]Object
Trees map[Hash]Object
Blobs map[Hash]Object
}

func NewRAWObjectStorage() *RAWObjectStorage {
return &RAWObjectStorage{
Objects: make(map[Hash]Object, 0),
Commits: make(map[Hash]Object, 0),
Trees: make(map[Hash]Object, 0),
Blobs: make(map[Hash]Object, 0),
}
}

func (o *RAWObjectStorage) New() (Object, error) {
return &RAWObject{}, nil
}

func (o *RAWObjectStorage) Set(obj Object) (Hash, error) {
h := obj.Hash()
o.Objects[h] = obj

switch obj.Type() {
case CommitObject:
o.Commits[h] = o.Objects[h]
case TreeObject:
o.Trees[h] = o.Objects[h]
case BlobObject:
o.Blobs[h] = o.Objects[h]
}

return h, nil
}

func (o *RAWObjectStorage) Get(h Hash) (Object, error) {
obj, ok := o.Objects[h]
if !ok {
return nil, ObjectNotFoundErr
}

return obj, nil
}

func (o *RAWObjectStorage) Iter(t ObjectType) ObjectIter {
var series []Object
switch t {
case CommitObject:
series = flattenObjectMap(o.Commits)
case TreeObject:
series = flattenObjectMap(o.Trees)
case BlobObject:
series = flattenObjectMap(o.Blobs)
}
return NewObjectSliceIter(series)
}

func flattenObjectMap(m map[Hash]Object) []Object {
objects := make([]Object, 0, len(m))
for _, obj := range m {
objects = append(objects, obj)
}
return objects
}
4 changes: 2 additions & 2 deletions formats/packfile/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func (r *Reader) readObjects(count uint32) error {
// of which 12-20 % is _not_ zlib inflation (ie. is our code).
for i := 0; i < int(count); i++ {
start := r.r.position
obj, err := r.newRAWObject()
obj, err := r.newObject()
if err != nil && err != io.EOF {
return err
}
Expand All @@ -143,7 +143,7 @@ func (r *Reader) readObjects(count uint32) error {
return nil
}

func (r *Reader) newRAWObject() (core.Object, error) {
func (r *Reader) newObject() (core.Object, error) {
raw, err := r.s.New()
if err != nil {
return nil, err
Expand Down
11 changes: 6 additions & 5 deletions formats/packfile/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"gopkg.in/src-d/go-git.v2/core"
"gopkg.in/src-d/go-git.v2/storages/memory"

"github.com/dustin/go-humanize"
. "gopkg.in/check.v1"
Expand All @@ -29,7 +30,7 @@ func (s *ReaderSuite) TestReadPackfile(c *C) {

r := NewReader(d)

storage := core.NewRAWObjectStorage()
storage := memory.NewObjectStorage()
_, err := r.Read(storage)
c.Assert(err, IsNil)

Expand Down Expand Up @@ -63,7 +64,7 @@ func (s *ReaderSuite) testReadPackfileGitFixture(c *C, file string, f Format) {
r := NewReader(d)
r.Format = f

storage := core.NewRAWObjectStorage()
storage := memory.NewObjectStorage()
_, err = r.Read(storage)
c.Assert(err, IsNil)

Expand Down Expand Up @@ -99,7 +100,7 @@ func (s *ReaderSuite) testReadPackfileGitFixture(c *C, file string, f Format) {
})
}

func AssertObjects(c *C, s *core.RAWObjectStorage, expects []string) {
func AssertObjects(c *C, s *memory.ObjectStorage, expects []string) {
c.Assert(len(expects), Equals, len(s.Objects))
for _, expected := range expects {
obtained, err := s.Get(core.NewHash(expected))
Expand Down Expand Up @@ -174,14 +175,14 @@ func (s *ReaderSuite) _TestMemoryREF(c *C) {
fmt.Println("time", time.Since(start))
}

func readFromFile(c *C, file string, f Format) *core.RAWObjectStorage {
func readFromFile(c *C, file string, f Format) *memory.ObjectStorage {
d, err := os.Open(file)
c.Assert(err, IsNil)

r := NewReader(d)
r.Format = f

storage := core.NewRAWObjectStorage()
storage := memory.NewObjectStorage()
_, err = r.Read(storage)
c.Assert(err, IsNil)

Expand Down
7 changes: 7 additions & 0 deletions objects.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package git

import (
"errors"
"fmt"
"io"
"strconv"
Expand All @@ -17,8 +18,14 @@ type Blob struct {
obj core.Object
}

var ErrUnsupportedObject = errors.New("unsupported object type")

// Decode transform an core.Object into a Blob struct
func (b *Blob) Decode(o core.Object) error {
if o.Type() != core.BlobObject {
return ErrUnsupportedObject
}

b.Hash = o.Hash()
b.Size = o.Size()
b.obj = o
Expand Down
3 changes: 2 additions & 1 deletion objects_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

. "gopkg.in/check.v1"
"gopkg.in/src-d/go-git.v2/core"
"gopkg.in/src-d/go-git.v2/storages/memory"
)

type ObjectsSuite struct {
Expand Down Expand Up @@ -71,7 +72,7 @@ func (s *ObjectsSuite) TestParseTree(c *C) {
}

func (s *ObjectsSuite) TestBlobHash(c *C) {
o := &core.RAWObject{}
o := &memory.Object{}
o.SetType(core.BlobObject)
o.SetSize(3)
o.Writer().Write([]byte{'F', 'O', 'O'})
Expand Down
4 changes: 2 additions & 2 deletions remote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package git

import (
"gopkg.in/src-d/go-git.v2/clients/http"
"gopkg.in/src-d/go-git.v2/core"
"gopkg.in/src-d/go-git.v2/formats/packfile"
"gopkg.in/src-d/go-git.v2/storages/memory"

. "gopkg.in/check.v1"
)
Expand Down Expand Up @@ -57,7 +57,7 @@ func (s *SuiteRemote) TestFetchDefaultBranch(c *C) {

pr := packfile.NewReader(reader)

storage := core.NewRAWObjectStorage()
storage := memory.NewObjectStorage()
_, err = pr.Read(storage)
c.Assert(err, IsNil)
c.Assert(storage.Objects, HasLen, 28)
Expand Down
3 changes: 2 additions & 1 deletion repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"gopkg.in/src-d/go-git.v2/clients/common"
"gopkg.in/src-d/go-git.v2/core"
"gopkg.in/src-d/go-git.v2/formats/packfile"
"gopkg.in/src-d/go-git.v2/storages/memory"
)

var (
Expand Down Expand Up @@ -49,7 +50,7 @@ func NewRepository(url string, auth common.AuthMethod) (*Repository, error) {
func NewPlainRepository() *Repository {
return &Repository{
Remotes: map[string]*Remote{},
Storage: core.NewRAWObjectStorage(),
Storage: memory.NewObjectStorage(),
}
}

Expand Down
55 changes: 55 additions & 0 deletions storage/memory/object.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package memory

import (
"bytes"
"io"

"gopkg.in/src-d/go-git.v2/core"
)

// Object on memory core.Object implementation
type Object struct {
t core.ObjectType
h core.Hash
content []byte
size int64
}

// Hash return the object Hash, the hash is calculated on-the-fly the first
// time is called, the subsequent calls the same Hash is returned even in the
// type or the content has changed. The Hash is only generated if the size of
// the content is exactly the Object.Size
func (o *Object) Hash() core.Hash {
if o.h == core.ZeroHash && int64(len(o.content)) == o.size {
o.h = core.ComputeHash(o.t, o.content)
}

return o.h
}

// Type return the core.ObjectType
func (o *Object) Type() core.ObjectType { return o.t }

// SetType sets the core.ObjectType
func (o *Object) SetType(t core.ObjectType) { o.t = t }

// Size return the size of the object
func (o *Object) Size() int64 { return o.size }

// SetSize set the object size, the given size should be written afterwards
func (o *Object) SetSize(s int64) { o.size = s }

// Reader returns a io.Reader used to read the object content
func (o *Object) Reader() io.Reader {
return bytes.NewBuffer(o.content)
}

// Writer returns a io.Writed used to write the object content
func (o *Object) Writer() io.Writer {
return o
}

func (o *Object) Write(p []byte) (n int, err error) {
o.content = append(o.content, p...)
return len(p), nil
}
67 changes: 67 additions & 0 deletions storage/memory/object_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package memory

import (
"io/ioutil"
"testing"

. "gopkg.in/check.v1"
"gopkg.in/src-d/go-git.v2/core"
)

func Test(t *testing.T) { TestingT(t) }

type ObjectSuite struct{}

var _ = Suite(&ObjectSuite{})

func (s *ObjectSuite) TestHash(c *C) {
o := &Object{}
o.SetType(core.BlobObject)
o.SetSize(14)

_, err := o.Write([]byte("Hello, World!\n"))
c.Assert(err, IsNil)

c.Assert(o.Hash().String(), Equals, "8ab686eafeb1f44702738c8b0f24f2567c36da6d")

o.SetType(core.CommitObject)
c.Assert(o.Hash().String(), Equals, "8ab686eafeb1f44702738c8b0f24f2567c36da6d")
}

func (s *ObjectSuite) TestHashNotFilled(c *C) {
o := &Object{}
o.SetType(core.BlobObject)
o.SetSize(14)

c.Assert(o.Hash(), Equals, core.ZeroHash)
}

func (s *ObjectSuite) TestType(c *C) {
o := &Object{}
o.SetType(core.BlobObject)
c.Assert(o.Type(), Equals, core.BlobObject)
}

func (s *ObjectSuite) TestSize(c *C) {
o := &Object{}
o.SetSize(42)
c.Assert(o.Size(), Equals, int64(42))
}

func (s *ObjectSuite) TestReader(c *C) {
o := &Object{content: []byte("foo")}

b, err := ioutil.ReadAll(o.Reader())
c.Assert(err, IsNil)
c.Assert(b, DeepEquals, []byte("foo"))
}

func (s *ObjectSuite) TestWriter(c *C) {
o := &Object{}

n, err := o.Writer().Write([]byte("foo"))
c.Assert(err, IsNil)
c.Assert(n, Equals, 3)

c.Assert(o.content, DeepEquals, []byte("foo"))
}
Loading