aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--obj.go8
-rw-r--r--obj_blob.go23
-rw-r--r--obj_commit.go20
-rw-r--r--obj_tag.go20
-rw-r--r--obj_tree.go22
-rw-r--r--objects_test.go4
-rw-r--r--repo_test.go20
7 files changed, 83 insertions, 34 deletions
diff --git a/obj.go b/obj.go
index de847607..ee11a024 100644
--- a/obj.go
+++ b/obj.go
@@ -33,6 +33,12 @@ type Object interface {
ObjectType() ObjectType
}
+// StoredObject describes a Git object with a known hash.
+type StoredObject interface {
+ Object
+ Hash() Hash
+}
+
func headerForType(ty ObjectType, body []byte) ([]byte, error) {
var tyStr string
switch ty {
@@ -59,7 +65,7 @@ func headerForType(ty ObjectType, body []byte) ([]byte, error) {
return buf.Bytes(), nil
}
-func parseObjectBody(ty ObjectType, id Hash, body []byte, repo *Repository) (Object, error) {
+func parseObjectBody(ty ObjectType, id Hash, body []byte, repo *Repository) (StoredObject, error) {
switch ty {
case ObjectTypeBlob:
return parseBlob(id, body)
diff --git a/obj_blob.go b/obj_blob.go
index c25f88eb..6a987604 100644
--- a/obj_blob.go
+++ b/obj_blob.go
@@ -2,22 +2,33 @@ package furgit
// Blob represents the contents of a Git blob.
type Blob struct {
- Hash Hash
-
Data []byte
}
+// StoredBlob represents a blob stored in the object database.
+type StoredBlob struct {
+ Blob
+ hash Hash
+}
+
+// Hash returns the hash of the stored blob.
+func (sBlob *StoredBlob) Hash() Hash {
+ return sBlob.hash
+}
+
// ObjectType allows Blob to satisfy the Object interface.
func (blob *Blob) ObjectType() ObjectType {
_ = blob
return ObjectTypeBlob
}
-func parseBlob(id Hash, body []byte) (*Blob, error) {
+func parseBlob(id Hash, body []byte) (*StoredBlob, error) {
data := append([]byte(nil), body...)
- return &Blob{
- Hash: id,
- Data: data,
+ return &StoredBlob{
+ hash: id,
+ Blob: Blob{
+ Data: data,
+ },
}, nil
}
diff --git a/obj_commit.go b/obj_commit.go
index f1616fba..c3a4e5db 100644
--- a/obj_commit.go
+++ b/obj_commit.go
@@ -6,9 +6,8 @@ import (
"fmt"
)
-// Commit mirrors the structure of a Git commit object.
+// Commit represents a Git commit object.
type Commit struct {
- Hash Hash
Tree Hash
Parents []Hash
Author Ident
@@ -17,15 +16,26 @@ type Commit struct {
ExtraHeaders []ExtraHeader
}
+// StoredCommit represents a commit stored in the object database.
+type StoredCommit struct {
+ Commit
+ hash Hash
+}
+
+// Hash returns the hash of the stored commit.
+func (sCommit *StoredCommit) Hash() Hash {
+ return sCommit.hash
+}
+
// ObjectType allows Commit to satisfy the Object interface.
func (commit *Commit) ObjectType() ObjectType {
_ = commit
return ObjectTypeCommit
}
-func parseCommit(id Hash, body []byte, repo *Repository) (*Commit, error) {
- c := new(Commit)
- c.Hash = id
+func parseCommit(id Hash, body []byte, repo *Repository) (*StoredCommit, error) {
+ c := new(StoredCommit)
+ c.hash = id
i := 0
for i < len(body) {
rel := bytes.IndexByte(body[i:], '\n')
diff --git a/obj_tag.go b/obj_tag.go
index 20088f17..2157e251 100644
--- a/obj_tag.go
+++ b/obj_tag.go
@@ -6,9 +6,8 @@ import (
"fmt"
)
-// Tag models an annotated Git tag object.
+// Tag represents an annotated Git tag object.
type Tag struct {
- Hash Hash
Target Hash
TargetType ObjectType
Name []byte
@@ -16,6 +15,17 @@ type Tag struct {
Message []byte
}
+// StoredTag represents a tag stored in the object database.
+type StoredTag struct {
+ Tag
+ hash Hash
+}
+
+// Hash returns the hash of the stored tag.
+func (sTag *StoredTag) Hash() Hash {
+ return sTag.hash
+}
+
// ObjectType allows Tag to satisfy the Object interface.
func (tag *Tag) ObjectType() ObjectType {
_ = tag
@@ -23,9 +33,9 @@ func (tag *Tag) ObjectType() ObjectType {
}
// parseTag parses a tag object body.
-func parseTag(id Hash, body []byte, repo *Repository) (*Tag, error) {
- t := new(Tag)
- t.Hash = id
+func parseTag(id Hash, body []byte, repo *Repository) (*StoredTag, error) {
+ t := new(StoredTag)
+ t.hash = id
i := 0
var haveTarget, haveType bool
diff --git a/obj_tree.go b/obj_tree.go
index 36c98950..eb926832 100644
--- a/obj_tree.go
+++ b/obj_tree.go
@@ -9,10 +9,20 @@ import (
// Tree represents a Git tree object.
type Tree struct {
- Hash Hash
Entries []TreeEntry
}
+// StoredTree represents a tree stored in the object database.
+type StoredTree struct {
+ Tree
+ hash Hash
+}
+
+// Hash returns the hash of the stored tree.
+func (sTree *StoredTree) Hash() Hash {
+ return sTree.hash
+}
+
// TreeEntry represents a single entry in a Git tree.
type TreeEntry struct {
Mode uint32
@@ -27,7 +37,7 @@ func (tree *Tree) ObjectType() ObjectType {
}
// parseTree decodes a tree body.
-func parseTree(id Hash, body []byte, repo *Repository) (*Tree, error) {
+func parseTree(id Hash, body []byte, repo *Repository) (*StoredTree, error) {
var entries []TreeEntry
i := 0
for i < len(body) {
@@ -66,9 +76,11 @@ func parseTree(id Hash, body []byte, repo *Repository) (*Tree, error) {
entries = append(entries, entry)
}
- return &Tree{
- Hash: id,
- Entries: entries,
+ return &StoredTree{
+ hash: id,
+ Tree: Tree{
+ Entries: entries,
+ },
}, nil
}
diff --git a/objects_test.go b/objects_test.go
index 141ba1d7..b191b865 100644
--- a/objects_test.go
+++ b/objects_test.go
@@ -58,8 +58,8 @@ func TestParseBlobAndSerialize(t *testing.T) {
if !bytes.Equal(blob.Data, data) {
t.Fatalf("blob data mismatch: %q", blob.Data)
}
- if blob.Hash != id {
- t.Fatalf("blob hash mismatch: %v", blob.Hash)
+ if blob.Hash() != id {
+ t.Fatalf("blob hash mismatch: %v", blob.Hash())
}
raw, err := blob.Serialize()
if err != nil {
diff --git a/repo_test.go b/repo_test.go
index 4f43f33d..b1b48df4 100644
--- a/repo_test.go
+++ b/repo_test.go
@@ -37,9 +37,9 @@ func TestOpenRepositoryAndLooseRead(t *testing.T) {
if err != nil {
t.Fatalf("looseRead error: %v", err)
}
- blob, ok := obj.(*Blob)
+ blob, ok := obj.(*StoredBlob)
if !ok {
- t.Fatalf("expected Blob, got %T", obj)
+ t.Fatalf("expected StoredBlob, got %T", obj)
}
if string(blob.Data) != "loose blob payload" {
t.Fatalf("blob data mismatch: %q", blob.Data)
@@ -225,8 +225,8 @@ func TestWriteLooseObjectAllTypes(t *testing.T) {
if err != nil {
t.Fatalf("ReadObject Blob error: %v", err)
}
- if rb, ok := readBlob.(*Blob); !ok {
- t.Fatalf("expected Blob, got %T", readBlob)
+ if rb, ok := readBlob.(*StoredBlob); !ok {
+ t.Fatalf("expected StoredBlob, got %T", readBlob)
} else if string(rb.Data) != "test blob data" {
t.Fatalf("blob data mismatch: %q", rb.Data)
}
@@ -245,8 +245,8 @@ func TestWriteLooseObjectAllTypes(t *testing.T) {
if err != nil {
t.Fatalf("ReadObject Tree error: %v", err)
}
- if rt, ok := readTree.(*Tree); !ok {
- t.Fatalf("expected Tree, got %T", readTree)
+ if rt, ok := readTree.(*StoredTree); !ok {
+ t.Fatalf("expected StoredTree, got %T", readTree)
} else if len(rt.Entries) != 1 {
t.Fatalf("tree entries mismatch: %d", len(rt.Entries))
}
@@ -276,8 +276,8 @@ func TestWriteLooseObjectAllTypes(t *testing.T) {
if err != nil {
t.Fatalf("ReadObject Commit error: %v", err)
}
- if rc, ok := readCommit.(*Commit); !ok {
- t.Fatalf("expected Commit, got %T", readCommit)
+ if rc, ok := readCommit.(*StoredCommit); !ok {
+ t.Fatalf("expected StoredCommit, got %T", readCommit)
} else if rc.Tree != treeID {
t.Fatalf("commit tree mismatch")
}
@@ -303,8 +303,8 @@ func TestWriteLooseObjectAllTypes(t *testing.T) {
if err != nil {
t.Fatalf("ReadObject Tag error: %v", err)
}
- if rtag, ok := readTag.(*Tag); !ok {
- t.Fatalf("expected Tag, got %T", readTag)
+ if rtag, ok := readTag.(*StoredTag); !ok {
+ t.Fatalf("expected StoredTag, got %T", readTag)
} else if rtag.Target != commitID {
t.Fatalf("tag target mismatch")
}