git2go/tree.go

157 lines
3.2 KiB
Go
Raw Normal View History

2013-03-05 13:53:04 -06:00
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"
2013-03-05 13:53:04 -06:00
"unsafe"
)
type Filemode int
const (
FilemodeNew Filemode = C.GIT_FILEMODE_NEW
FilemodeTree = C.GIT_FILEMODE_TREE
FilemodeBlob = C.GIT_FILEMODE_BLOB
FilemodeBlobExecutable = C.GIT_FILEMODE_BLOB_EXECUTABLE
FilemodeLink = C.GIT_FILEMODE_LINK
FilemodeCommit = C.GIT_FILEMODE_COMMIT
)
2013-03-05 13:53:04 -06:00
type Tree struct {
2013-04-17 17:54:46 -05:00
gitObject
2013-04-16 16:04:35 -05:00
}
2013-03-05 13:53:04 -06:00
type TreeEntry struct {
Name string
Id *Oid
2013-04-26 16:28:32 -05:00
Type ObjectType
Filemode int
2013-03-05 13:53:04 -06:00
}
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)),
2013-04-26 16:28:32 -05:00
ObjectType(C.git_tree_entry_type(entry)),
int(C.git_tree_entry_filemode(entry)),
2013-03-05 13:53:04 -06:00
}
}
2013-04-17 17:54:46 -05:00
func (t Tree) EntryByName(filename string) *TreeEntry {
2013-03-05 13:53:04 -06:00
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)
}
// EntryByPath looks up an entry by its full path, recursing into
// deeper trees if necessary (i.e. if there are slashes in the path)
func (t Tree) EntryByPath(path string) (*TreeEntry, error) {
cpath := C.CString(path)
defer C.free(unsafe.Pointer(cpath))
var entry *C.git_tree_entry
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_tree_entry_bypath(&entry, t.ptr, cpath)
if ret < 0 {
2014-02-26 09:14:31 -06:00
return nil, MakeGitError(ret)
}
return newTreeEntry(entry), nil
}
2013-04-17 17:54:46 -05:00
func (t Tree) EntryByIndex(index uint64) *TreeEntry {
2013-03-05 13:53:04 -06:00
entry := C.git_tree_entry_byindex(t.ptr, C.size_t(index))
if entry == nil {
return nil
}
return newTreeEntry(entry)
}
2013-04-17 17:54:46 -05:00
func (t Tree) EntryCount() uint64 {
2013-03-05 13:53:04 -06:00
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)))
}
2013-04-17 17:54:46 -05:00
func (t Tree) Walk(callback TreeWalkCallback) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
2013-03-05 13:53:04 -06:00
err := C._go_git_treewalk(
t.ptr,
C.GIT_TREEWALK_PRE,
unsafe.Pointer(&callback),
)
if err < 0 {
return MakeGitError(err)
2013-03-05 13:53:04 -06:00
}
return nil
}
type TreeBuilder struct {
ptr *C.git_treebuilder
repo *Repository
}
func (v *TreeBuilder) Free() {
runtime.SetFinalizer(v, nil)
2013-03-05 13:53:04 -06:00
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))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
2013-03-05 13:53:04 -06:00
err := C.git_treebuilder_insert(nil, v.ptr, cfilename, id.toC(), C.git_filemode_t(filemode))
if err < 0 {
return MakeGitError(err)
2013-03-05 13:53:04 -06:00
}
return nil
}
func (v *TreeBuilder) Write() (*Oid, error) {
oid := new(Oid)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
2013-03-05 13:53:04 -06:00
err := C.git_treebuilder_write(oid.toC(), v.repo.ptr, v.ptr)
if err < 0 {
return nil, MakeGitError(err)
2013-03-05 13:53:04 -06:00
}
return oid, nil
}