forked from coveord/git2go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtree.go
129 lines (100 loc) · 2.37 KB
/
tree.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package git
/*
#include <git2.h>
#include <git2/errors.h>
extern int _go_git_treewalk(git_tree *tree, git_treewalk_mode mode, void *ptr);
*/
import "C"
import (
"runtime"
"unsafe"
)
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
Type int
}
func newTreeEntry(entry *C.git_tree_entry) *TreeEntry {
return &TreeEntry{
C.GoString(C.git_tree_entry_name(entry)),
newOidFromC(C.git_tree_entry_id(entry)),
int(C.git_tree_entry_type(entry)),
}
}
func (t *Tree) EntryByName(filename string) *TreeEntry {
cname := C.CString(filename)
defer C.free(unsafe.Pointer(cname))
entry := C.git_tree_entry_byname(t.ptr, cname)
if entry == nil {
return nil
}
return newTreeEntry(entry)
}
func (t *Tree) EntryByIndex(index uint64) *TreeEntry {
entry := C.git_tree_entry_byindex(t.ptr, C.size_t(index))
if entry == nil {
return nil
}
return newTreeEntry(entry)
}
func (t *Tree) EntryCount() uint64 {
num := C.git_tree_entrycount(t.ptr)
return uint64(num)
}
type TreeWalkCallback func(string, *TreeEntry) int
//export CallbackGitTreeWalk
func CallbackGitTreeWalk(_root unsafe.Pointer, _entry unsafe.Pointer, ptr unsafe.Pointer) C.int {
root := C.GoString((*C.char)(_root))
entry := (*C.git_tree_entry)(_entry)
callback := *(*TreeWalkCallback)(ptr)
return C.int(callback(root, newTreeEntry(entry)))
}
func (t *Tree) Walk(callback TreeWalkCallback) error {
err := C._go_git_treewalk(
t.ptr,
C.GIT_TREEWALK_PRE,
unsafe.Pointer(&callback),
)
if err < 0 {
return LastError()
}
return nil
}
type TreeBuilder struct {
ptr *C.git_treebuilder
repo *Repository
}
func (v *TreeBuilder) Free() {
runtime.SetFinalizer(v, nil)
C.git_treebuilder_free(v.ptr)
}
func (v *TreeBuilder) Insert(filename string, id *Oid, filemode int) (error) {
cfilename := C.CString(filename)
defer C.free(unsafe.Pointer(cfilename))
err := C.git_treebuilder_insert(nil, v.ptr, cfilename, id.toC(), C.git_filemode_t(filemode))
if err < 0 {
return LastError()
}
return nil
}
func (v *TreeBuilder) Write() (*Oid, error) {
oid := new(Oid)
err := C.git_treebuilder_write(oid.toC(), v.repo.ptr, v.ptr)
if err < 0 {
return nil, LastError()
}
return oid, nil
}