Skip to content

Commit d190d8a

Browse files
author
Vicent Marti
committed
Take 2 on polymorphism
1 parent c728651 commit d190d8a

File tree

6 files changed

+112
-53
lines changed

6 files changed

+112
-53
lines changed

blob.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,25 @@ package git
77
*/
88
import "C"
99
import (
10-
"runtime"
1110
"unsafe"
11+
"runtime"
1212
)
1313

1414
type Blob struct {
15-
ptr *C.git_object
15+
ptr *C.git_blob
16+
}
17+
18+
func (o *Blob) Id() *Oid {
19+
return newOidFromC(C.git_blob_id(o.ptr))
20+
}
21+
22+
func (o *Blob) Type() ObjectType {
23+
return OBJ_BLOB
1624
}
1725

18-
func (v *Blob) Free() {
19-
runtime.SetFinalizer(v, nil)
20-
C.git_object_free(v.ptr)
26+
func (o *Blob) Free() {
27+
runtime.SetFinalizer(o, nil)
28+
C.git_blob_free(o.ptr)
2129
}
2230

2331
func (v *Blob) Size() int64 {

commit.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,32 @@ type Commit struct {
1919
ptr *C.git_commit
2020
}
2121

22-
func (c *Commit) Id() *Oid {
23-
return newOidFromC(C.git_commit_id(c.ptr))
22+
func (o *Commit) Id() *Oid {
23+
return newOidFromC(C.git_commit_id(o.ptr))
24+
}
25+
26+
func (o *Commit) Type() ObjectType {
27+
return OBJ_COMMIT
28+
}
29+
30+
func (o *Commit) Free() {
31+
runtime.SetFinalizer(o, nil)
32+
C.git_commit_free(o.ptr)
2433
}
2534

2635
func (c *Commit) Message() string {
2736
return C.GoString(C.git_commit_message(c.ptr))
2837
}
2938

3039
func (c *Commit) Tree() (*Tree, error) {
31-
tree := new(Tree)
40+
var ptr *C.git_object
3241

33-
err := C.git_commit_tree(&tree.ptr, c.ptr)
42+
err := C.git_commit_tree(&ptr, c.ptr)
3443
if err < 0 {
3544
return nil, LastError()
3645
}
3746

38-
runtime.SetFinalizer(tree, (*Tree).Free)
39-
return tree, nil
47+
return allocObject(ptr).(*Tree), nil
4048
}
4149

4250
func (c *Commit) TreeId() *Oid {

object.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package git
2+
3+
/*
4+
#cgo pkg-config: libgit2
5+
#include <git2.h>
6+
#include <git2/errors.h>
7+
*/
8+
import "C"
9+
import "runtime"
10+
11+
type ObjectType int
12+
13+
var (
14+
OBJ_ANY ObjectType = C.GIT_OBJ_ANY
15+
OBJ_BAD ObjectType = C.GIT_OBJ_BAD
16+
OBJ_COMMIT ObjectType = C.GIT_OBJ_COMMIT
17+
OBJ_TREE ObjectType = C.GIT_OBJ_TREE
18+
OBJ_BLOB ObjectType = C.GIT_OBJ_BLOB
19+
OBJ_TAG ObjectType = C.GIT_OBJ_TAG
20+
)
21+
22+
type Object interface {
23+
Free()
24+
Id() *Oid
25+
Type() ObjectType
26+
}
27+
28+
func allocObject(cobj *C.git_object) Object {
29+
var object Object
30+
31+
switch ObjectType(C.git_object_type(cobj)) {
32+
case OBJ_COMMIT:
33+
object = &Commit{cobj}
34+
runtime.SetFinalizer(object, (*Commit).Free)
35+
36+
case OBJ_TREE:
37+
object = &Tree{cobj}
38+
runtime.SetFinalizer(object, (*Tree).Free)
39+
40+
case OBJ_BLOB:
41+
object = &Blob{cobj}
42+
runtime.SetFinalizer(object, (*Blob).Free)
43+
44+
default:
45+
return nil
46+
}
47+
48+
return object
49+
}

odb.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,6 @@ import (
1212
"runtime"
1313
)
1414

15-
var (
16-
OBJ_ANY = C.GIT_OBJ_ANY
17-
OBJ_BAD = C.GIT_OBJ_BAD
18-
OBJ_COMMIT = C.GIT_OBJ_COMMIT
19-
OBJ_TREE = C.GIT_OBJ_TREE
20-
OBJ_BLOB = C.GIT_OBJ_BLOB
21-
OBJ_TAG = C.GIT_OBJ_TAG
22-
)
23-
2415
type Odb struct {
2516
ptr *C.git_odb
2617
}

repository.go

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -72,35 +72,41 @@ func (v *Repository) Index() (*Index, error) {
7272
return newIndexFromC(ptr), nil
7373
}
7474

75-
func (v *Repository) LookupTree(oid *Oid) (*Tree, error) {
76-
tree := new(Tree)
77-
ret := C.git_tree_lookup(&tree.ptr, v.ptr, oid.toC())
75+
func (v *Repository) Lookup(oid *Oid, t ObjectType) (Object, error) {
76+
var ptr *C.git_object
77+
ret := C.git_object_lookup(&ptr, v.ptr, oid.toC(), C.git_otype(t))
7878
if ret < 0 {
7979
return nil, LastError()
8080
}
8181

82-
return tree, nil
82+
return allocObject(ptr), nil
8383
}
8484

85-
func (v *Repository) LookupCommit(o *Oid) (*Commit, error) {
86-
commit := new(Commit)
87-
ecode := C.git_commit_lookup(&commit.ptr, v.ptr, o.toC())
88-
if ecode < 0 {
89-
return nil, LastError()
85+
func (v *Repository) LookupTree(oid *Oid) (*Tree, error) {
86+
obj, err := v.Lookup(oid, OBJ_TREE)
87+
if err != nil {
88+
return nil, err
9089
}
9190

92-
return commit, nil
91+
return obj.(*Tree), nil
9392
}
9493

95-
func (v *Repository) LookupBlob(o *Oid) (*Blob, error) {
96-
blob := new(Blob)
97-
ecode := C.git_blob_lookup(&blob.ptr, v.ptr, o.toC())
98-
if ecode < 0 {
99-
return nil, LastError()
94+
func (v *Repository) LookupCommit(oid *Oid) (*Commit, error) {
95+
obj, err := v.Lookup(oid, OBJ_COMMIT)
96+
if err != nil {
97+
return nil, err
98+
}
99+
100+
return obj.(*Commit), nil
101+
}
102+
103+
func (v *Repository) LookupBlob(oid *Oid) (*Blob, error) {
104+
obj, err := v.Lookup(oid, OBJ_BLOB)
105+
if err != nil {
106+
return nil, err
100107
}
101108

102-
runtime.SetFinalizer(blob, (*Blob).Free)
103-
return blob, nil
109+
return obj.(*Blob), nil
104110
}
105111

106112
func (v *Repository) LookupReference(name string) (*Reference, error) {

tree.go

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@ type Tree struct {
1717
ptr *C.git_tree
1818
}
1919

20+
func (o *Tree) Id() *Oid {
21+
return newOidFromC(C.git_tree_id(o.ptr))
22+
}
23+
24+
func (o *Tree) Type() ObjectType {
25+
return OBJ_TREE
26+
}
27+
28+
func (o *Tree) Free() {
29+
runtime.SetFinalizer(o, nil)
30+
C.git_tree_free(o.ptr)
31+
}
32+
2033
type TreeEntry struct {
2134
Name string
2235
Id *Oid
@@ -31,22 +44,6 @@ func newTreeEntry(entry *C.git_tree_entry) *TreeEntry {
3144
}
3245
}
3346

34-
func (t *Tree) Free() {
35-
runtime.SetFinalizer(t, nil)
36-
C.git_tree_free(t.ptr)
37-
}
38-
39-
func TreeLookup(repo *Repository, oid *Oid) (*Tree, error) {
40-
tree := new(Tree)
41-
err := C.git_tree_lookup(&tree.ptr, repo.ptr, oid.toC())
42-
if err < 0 {
43-
return nil, LastError()
44-
}
45-
46-
runtime.SetFinalizer(tree, (*Tree).Free)
47-
return tree, nil
48-
}
49-
5047
func (t *Tree) EntryByName(filename string) *TreeEntry {
5148
cname := C.CString(filename)
5249
defer C.free(unsafe.Pointer(cname))

0 commit comments

Comments
 (0)