aboutsummaryrefslogtreecommitdiffstats
path: root/objects.go
diff options
context:
space:
mode:
Diffstat (limited to 'objects.go')
-rw-r--r--objects.go167
1 files changed, 80 insertions, 87 deletions
diff --git a/objects.go b/objects.go
index 77bdc2a..a82a73b 100644
--- a/objects.go
+++ b/objects.go
@@ -1,155 +1,148 @@
package git
import (
+ "bufio"
"bytes"
- "encoding/hex"
"fmt"
+ "io"
+ "os"
"strconv"
"time"
- "gopkg.in/src-d/go-git.v2/common"
+ "gopkg.in/src-d/go-git.v2/internal"
)
-// Object generic object interface
-type Object interface {
- Type() common.ObjectType
- Hash() common.Hash
-}
-
// Commit points to a single tree, marking it as what the project looked like
// at a certain point in time. It contains meta-information about that point
// in time, such as a timestamp, the author of the changes since the last
// commit, a pointer to the previous commit(s), etc.
// http://schacon.github.io/gitbook/1_the_git_object_model.html
type Commit struct {
- Tree common.Hash
- Parents []common.Hash
+ Hash internal.Hash
+ Tree internal.Hash
+ Parents []internal.Hash
Author Signature
Committer Signature
Message string
- hash common.Hash
}
-// ParseCommit transform a byte slice into a Commit struct
-func ParseCommit(b []byte) (*Commit, error) {
- o := &Commit{hash: common.ComputeHash(common.CommitObject, b)}
+// Decode transform an internal.Object into a Blob struct
+func (c *Commit) Decode(o internal.Object) error {
+ c.Hash = o.Hash()
+ r := bufio.NewReader(o.Reader())
- lines := bytes.Split(b, []byte{'\n'})
- for i := range lines {
- if len(lines[i]) > 0 {
- var err error
+ var message bool
+ for {
+ line, err := r.ReadSlice('\n')
+ if err != nil && err != io.EOF {
+ return err
+ }
- split := bytes.SplitN(lines[i], []byte{' '}, 2)
+ line = bytes.TrimSpace(line)
+ if !message {
+ if len(line) == 0 {
+ message = true
+ continue
+ }
+
+ split := bytes.SplitN(line, []byte{' '}, 2)
switch string(split[0]) {
case "tree":
- _, err = hex.Decode(o.Tree[:], split[1])
+ c.Tree = internal.NewHash(string(split[1]))
case "parent":
- var h common.Hash
- _, err = hex.Decode(h[:], split[1])
- if err == nil {
- o.Parents = append(o.Parents, h)
- }
+ c.Parents = append(c.Parents, internal.NewHash(string(split[1])))
case "author":
- o.Author = ParseSignature(split[1])
+ c.Author = ParseSignature(split[1])
case "committer":
- o.Committer = ParseSignature(split[1])
- }
-
- if err != nil {
- return nil, err
+ c.Committer = ParseSignature(split[1])
}
} else {
- o.Message = string(bytes.Join(append(lines[i+1:]), []byte{'\n'}))
- break
+ c.Message += string(line) + "\n"
}
+ if err == io.EOF {
+ return nil
+ }
}
-
- return o, nil
-}
-
-// Type returns the object type
-func (o *Commit) Type() common.ObjectType {
- return common.CommitObject
-}
-
-// Hash returns the computed hash of the commit
-func (o *Commit) Hash() common.Hash {
- return o.hash
}
// Tree is basically like a directory - it references a bunch of other trees
// and/or blobs (i.e. files and sub-directories)
type Tree struct {
Entries []TreeEntry
- hash common.Hash
+ Hash internal.Hash
}
// TreeEntry represents a file
type TreeEntry struct {
Name string
- Hash common.Hash
+ Mode os.FileMode
+ Hash internal.Hash
}
-// ParseTree transform a byte slice into a Tree struct
-func ParseTree(b []byte) (*Tree, error) {
- o := &Tree{hash: common.ComputeHash(common.TreeObject, b)}
-
- if len(b) == 0 {
- return o, nil
+// Decode transform an internal.Object into a Tree struct
+func (t *Tree) Decode(o internal.Object) error {
+ t.Hash = o.Hash()
+ if o.Size() == 0 {
+ return nil
}
+ r := bufio.NewReader(o.Reader())
for {
- split := bytes.SplitN(b, []byte{0}, 2)
- split1 := bytes.SplitN(split[0], []byte{' '}, 2)
+ mode, err := r.ReadString(' ')
+ if err != nil {
+ if err == io.EOF {
+ break
+ }
- entry := TreeEntry{}
- entry.Name = string(split1[1])
- copy(entry.Hash[:], split[1][0:20])
+ return err
+ }
- o.Entries = append(o.Entries, entry)
+ fm, err := strconv.ParseInt(mode[:len(mode)-1], 8, 32)
+ if err != nil && err != io.EOF {
+ return err
+ }
- b = split[1][20:]
- if len(split[1]) == 20 {
- break
+ name, err := r.ReadString(0)
+ if err != nil && err != io.EOF {
+ return err
}
- }
- return o, nil
-}
+ var hash internal.Hash
+ _, err = r.Read(hash[:])
+ if err != nil && err != io.EOF {
+ return err
+ }
-// Type returns the object type
-func (o *Tree) Type() common.ObjectType {
- return common.TreeObject
-}
+ t.Entries = append(t.Entries, TreeEntry{
+ Hash: hash,
+ Mode: os.FileMode(fm),
+ Name: name[:len(name)-1],
+ })
+ }
-// Hash returns the computed hash of the tree
-func (o *Tree) Hash() common.Hash {
- return o.hash
+ return nil
}
// Blob is used to store file data - it is generally a file.
type Blob struct {
- Len int
- hash common.Hash
+ Hash internal.Hash
+ Size int64
+ obj internal.Object
}
-// ParseBlob transform a byte slice into a Blob struct
-func ParseBlob(b []byte) (*Blob, error) {
- return &Blob{
- Len: len(b),
- hash: common.ComputeHash(common.BlobObject, b),
- }, nil
-}
+// Decode transform an internal.Object into a Blob struct
+func (b *Blob) Decode(o internal.Object) error {
+ b.Hash = o.Hash()
+ b.Size = o.Size()
+ b.obj = o
-// Type returns the object type
-func (o *Blob) Type() common.ObjectType {
- return common.BlobObject
+ return nil
}
-// Hash returns the computed hash of the blob
-func (o *Blob) Hash() common.Hash {
- return o.hash
+// Reader returns a reader allow the access to the content of the blob
+func (b *Blob) Reader() io.Reader {
+ return b.obj.Reader()
}
// Signature represents an action signed by a person