summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blob.go18
-rw-r--r--commit.go20
-rw-r--r--object.go49
-rw-r--r--odb.go9
-rw-r--r--repository.go40
-rw-r--r--tree.go29
6 files changed, 112 insertions, 53 deletions
diff --git a/blob.go b/blob.go
index 73e3ab3..ee50a15 100644
--- a/blob.go
+++ b/blob.go
@@ -7,17 +7,25 @@ package git
*/
import "C"
import (
- "runtime"
"unsafe"
+ "runtime"
)
type Blob struct {
- ptr *C.git_object
+ ptr *C.git_blob
+}
+
+func (o *Blob) Id() *Oid {
+ return newOidFromC(C.git_blob_id(o.ptr))
+}
+
+func (o *Blob) Type() ObjectType {
+ return OBJ_BLOB
}
-func (v *Blob) Free() {
- runtime.SetFinalizer(v, nil)
- C.git_object_free(v.ptr)
+func (o *Blob) Free() {
+ runtime.SetFinalizer(o, nil)
+ C.git_blob_free(o.ptr)
}
func (v *Blob) Size() int64 {
diff --git a/commit.go b/commit.go
index d31f684..b1ca6c4 100644
--- a/commit.go
+++ b/commit.go
@@ -19,8 +19,17 @@ type Commit struct {
ptr *C.git_commit
}
-func (c *Commit) Id() *Oid {
- return newOidFromC(C.git_commit_id(c.ptr))
+func (o *Commit) Id() *Oid {
+ return newOidFromC(C.git_commit_id(o.ptr))
+}
+
+func (o *Commit) Type() ObjectType {
+ return OBJ_COMMIT
+}
+
+func (o *Commit) Free() {
+ runtime.SetFinalizer(o, nil)
+ C.git_commit_free(o.ptr)
}
func (c *Commit) Message() string {
@@ -28,15 +37,14 @@ func (c *Commit) Message() string {
}
func (c *Commit) Tree() (*Tree, error) {
- tree := new(Tree)
+ var ptr *C.git_object
- err := C.git_commit_tree(&tree.ptr, c.ptr)
+ err := C.git_commit_tree(&ptr, c.ptr)
if err < 0 {
return nil, LastError()
}
- runtime.SetFinalizer(tree, (*Tree).Free)
- return tree, nil
+ return allocObject(ptr).(*Tree), nil
}
func (c *Commit) TreeId() *Oid {
diff --git a/object.go b/object.go
new file mode 100644
index 0000000..0d55409
--- /dev/null
+++ b/object.go
@@ -0,0 +1,49 @@
+package git
+
+/*
+#cgo pkg-config: libgit2
+#include <git2.h>
+#include <git2/errors.h>
+*/
+import "C"
+import "runtime"
+
+type ObjectType int
+
+var (
+ OBJ_ANY ObjectType = C.GIT_OBJ_ANY
+ OBJ_BAD ObjectType = C.GIT_OBJ_BAD
+ OBJ_COMMIT ObjectType = C.GIT_OBJ_COMMIT
+ OBJ_TREE ObjectType = C.GIT_OBJ_TREE
+ OBJ_BLOB ObjectType = C.GIT_OBJ_BLOB
+ OBJ_TAG ObjectType = C.GIT_OBJ_TAG
+)
+
+type Object interface {
+ Free()
+ Id() *Oid
+ Type() ObjectType
+}
+
+func allocObject(cobj *C.git_object) Object {
+ var object Object
+
+ switch ObjectType(C.git_object_type(cobj)) {
+ case OBJ_COMMIT:
+ object = &Commit{cobj}
+ runtime.SetFinalizer(object, (*Commit).Free)
+
+ case OBJ_TREE:
+ object = &Tree{cobj}
+ runtime.SetFinalizer(object, (*Tree).Free)
+
+ case OBJ_BLOB:
+ object = &Blob{cobj}
+ runtime.SetFinalizer(object, (*Blob).Free)
+
+ default:
+ return nil
+ }
+
+ return object
+}
diff --git a/odb.go b/odb.go
index bf17171..37d9fcd 100644
--- a/odb.go
+++ b/odb.go
@@ -12,15 +12,6 @@ import (
"runtime"
)
-var (
- OBJ_ANY = C.GIT_OBJ_ANY
- OBJ_BAD = C.GIT_OBJ_BAD
- OBJ_COMMIT = C.GIT_OBJ_COMMIT
- OBJ_TREE = C.GIT_OBJ_TREE
- OBJ_BLOB = C.GIT_OBJ_BLOB
- OBJ_TAG = C.GIT_OBJ_TAG
-)
-
type Odb struct {
ptr *C.git_odb
}
diff --git a/repository.go b/repository.go
index 3de4974..015e5bf 100644
--- a/repository.go
+++ b/repository.go
@@ -72,35 +72,41 @@ func (v *Repository) Index() (*Index, error) {
return newIndexFromC(ptr), nil
}
-func (v *Repository) LookupTree(oid *Oid) (*Tree, error) {
- tree := new(Tree)
- ret := C.git_tree_lookup(&tree.ptr, v.ptr, oid.toC())
+func (v *Repository) Lookup(oid *Oid, t ObjectType) (Object, error) {
+ var ptr *C.git_object
+ ret := C.git_object_lookup(&ptr, v.ptr, oid.toC(), C.git_otype(t))
if ret < 0 {
return nil, LastError()
}
- return tree, nil
+ return allocObject(ptr), nil
}
-func (v *Repository) LookupCommit(o *Oid) (*Commit, error) {
- commit := new(Commit)
- ecode := C.git_commit_lookup(&commit.ptr, v.ptr, o.toC())
- if ecode < 0 {
- return nil, LastError()
+func (v *Repository) LookupTree(oid *Oid) (*Tree, error) {
+ obj, err := v.Lookup(oid, OBJ_TREE)
+ if err != nil {
+ return nil, err
}
- return commit, nil
+ return obj.(*Tree), nil
}
-func (v *Repository) LookupBlob(o *Oid) (*Blob, error) {
- blob := new(Blob)
- ecode := C.git_blob_lookup(&blob.ptr, v.ptr, o.toC())
- if ecode < 0 {
- return nil, LastError()
+func (v *Repository) LookupCommit(oid *Oid) (*Commit, error) {
+ obj, err := v.Lookup(oid, OBJ_COMMIT)
+ if err != nil {
+ return nil, err
+ }
+
+ return obj.(*Commit), nil
+}
+
+func (v *Repository) LookupBlob(oid *Oid) (*Blob, error) {
+ obj, err := v.Lookup(oid, OBJ_BLOB)
+ if err != nil {
+ return nil, err
}
- runtime.SetFinalizer(blob, (*Blob).Free)
- return blob, nil
+ return obj.(*Blob), nil
}
func (v *Repository) LookupReference(name string) (*Reference, error) {
diff --git a/tree.go b/tree.go
index dc82929..d8a639c 100644
--- a/tree.go
+++ b/tree.go
@@ -17,6 +17,19 @@ type Tree struct {
ptr *C.git_tree
}
+func (o *Tree) Id() *Oid {
+ return newOidFromC(C.git_tree_id(o.ptr))
+}
+
+func (o *Tree) Type() ObjectType {
+ return OBJ_TREE
+}
+
+func (o *Tree) Free() {
+ runtime.SetFinalizer(o, nil)
+ C.git_tree_free(o.ptr)
+}
+
type TreeEntry struct {
Name string
Id *Oid
@@ -31,22 +44,6 @@ func newTreeEntry(entry *C.git_tree_entry) *TreeEntry {
}
}
-func (t *Tree) Free() {
- runtime.SetFinalizer(t, nil)
- C.git_tree_free(t.ptr)
-}
-
-func TreeLookup(repo *Repository, oid *Oid) (*Tree, error) {
- tree := new(Tree)
- err := C.git_tree_lookup(&tree.ptr, repo.ptr, oid.toC())
- if err < 0 {
- return nil, LastError()
- }
-
- runtime.SetFinalizer(tree, (*Tree).Free)
- return tree, nil
-}
-
func (t *Tree) EntryByName(filename string) *TreeEntry {
cname := C.CString(filename)
defer C.free(unsafe.Pointer(cname))