forked from libgit2/git2go
/
tree.go
132 lines (103 loc) · 2.49 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
130
131
132
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
}
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) 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))
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
}