2013-03-05 13:53:04 -06:00
|
|
|
package git
|
|
|
|
|
|
|
|
/*
|
|
|
|
#include <git2.h>
|
|
|
|
|
|
|
|
extern int _go_git_treewalk(git_tree *tree, git_treewalk_mode mode, void *ptr);
|
|
|
|
*/
|
|
|
|
import "C"
|
|
|
|
|
|
|
|
import (
|
2013-03-05 18:43:48 -06:00
|
|
|
"runtime"
|
2013-03-05 13:53:04 -06:00
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
2013-09-12 03:46:20 -05:00
|
|
|
type Filemode int
|
2014-03-07 18:43:20 -06:00
|
|
|
|
2013-09-09 07:21:16 -05:00
|
|
|
const (
|
2014-09-03 20:08:48 -05:00
|
|
|
FilemodeTree Filemode = C.GIT_FILEMODE_TREE
|
2014-10-20 10:53:10 -05:00
|
|
|
FilemodeBlob Filemode = C.GIT_FILEMODE_BLOB
|
|
|
|
FilemodeBlobExecutable Filemode = C.GIT_FILEMODE_BLOB_EXECUTABLE
|
|
|
|
FilemodeLink Filemode = C.GIT_FILEMODE_LINK
|
|
|
|
FilemodeCommit Filemode = C.GIT_FILEMODE_COMMIT
|
2013-09-09 07:21:16 -05:00
|
|
|
)
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
type Tree struct {
|
2015-08-04 07:47:10 -05:00
|
|
|
Object
|
2014-04-01 05:13:37 -05:00
|
|
|
cast_ptr *C.git_tree
|
2013-04-16 16:04:35 -05:00
|
|
|
}
|
|
|
|
|
2017-07-08 15:53:50 -05:00
|
|
|
func (t *Tree) AsObject() *Object {
|
|
|
|
return &t.Object
|
|
|
|
}
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
type TreeEntry struct {
|
2014-03-07 18:43:20 -06:00
|
|
|
Name string
|
|
|
|
Id *Oid
|
|
|
|
Type ObjectType
|
2014-10-20 10:53:10 -05:00
|
|
|
Filemode Filemode
|
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)),
|
2014-10-20 10:53:10 -05:00
|
|
|
Filemode(C.git_tree_entry_filemode(entry)),
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-17 02:19:36 -06: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))
|
|
|
|
|
2014-04-01 05:13:37 -05:00
|
|
|
entry := C.git_tree_entry_byname(t.cast_ptr, cname)
|
2013-03-05 13:53:04 -06:00
|
|
|
if entry == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-02-09 01:52:16 -06:00
|
|
|
goEntry := newTreeEntry(entry)
|
|
|
|
runtime.KeepAlive(t)
|
|
|
|
return goEntry
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
2015-07-24 11:46:57 -05:00
|
|
|
// EntryById performs a lookup for a tree entry with the given SHA value.
|
|
|
|
//
|
|
|
|
// It returns a *TreeEntry that is owned by the Tree. You don't have to
|
|
|
|
// free it, but you must not use it after the Tree is freed.
|
|
|
|
//
|
|
|
|
// Warning: this must examine every entry in the tree, so it is not fast.
|
2019-11-17 02:19:36 -06:00
|
|
|
func (t *Tree) EntryById(id *Oid) *TreeEntry {
|
2015-07-24 11:46:57 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
|
|
|
entry := C.git_tree_entry_byid(t.cast_ptr, id.toC())
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(id)
|
2015-07-24 11:46:57 -05:00
|
|
|
if entry == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-02-09 01:52:16 -06:00
|
|
|
goEntry := newTreeEntry(entry)
|
|
|
|
runtime.KeepAlive(t)
|
|
|
|
return goEntry
|
2015-07-24 11:46:57 -05:00
|
|
|
}
|
|
|
|
|
2013-09-12 01:56:47 -05:00
|
|
|
// EntryByPath looks up an entry by its full path, recursing into
|
|
|
|
// deeper trees if necessary (i.e. if there are slashes in the path)
|
2019-11-17 02:19:36 -06:00
|
|
|
func (t *Tree) EntryByPath(path string) (*TreeEntry, error) {
|
2013-09-12 01:56:47 -05:00
|
|
|
cpath := C.CString(path)
|
|
|
|
defer C.free(unsafe.Pointer(cpath))
|
|
|
|
var entry *C.git_tree_entry
|
|
|
|
|
2013-09-18 02:23:47 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2014-04-01 05:13:37 -05:00
|
|
|
ret := C.git_tree_entry_bypath(&entry, t.cast_ptr, cpath)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(t)
|
2013-09-12 01:56:47 -05:00
|
|
|
if ret < 0 {
|
2014-02-26 09:14:31 -06:00
|
|
|
return nil, MakeGitError(ret)
|
2013-09-12 01:56:47 -05:00
|
|
|
}
|
2017-02-24 15:55:14 -06:00
|
|
|
defer C.git_tree_entry_free(entry)
|
2013-09-12 01:56:47 -05:00
|
|
|
|
|
|
|
return newTreeEntry(entry), nil
|
|
|
|
}
|
|
|
|
|
2019-11-17 02:19:36 -06:00
|
|
|
func (t *Tree) EntryByIndex(index uint64) *TreeEntry {
|
2014-04-01 05:13:37 -05:00
|
|
|
entry := C.git_tree_entry_byindex(t.cast_ptr, C.size_t(index))
|
2013-03-05 13:53:04 -06:00
|
|
|
if entry == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-02-09 01:52:16 -06:00
|
|
|
goEntry := newTreeEntry(entry)
|
|
|
|
runtime.KeepAlive(t)
|
|
|
|
return goEntry
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
2019-11-17 02:19:36 -06:00
|
|
|
func (t *Tree) EntryCount() uint64 {
|
2014-04-01 05:13:37 -05:00
|
|
|
num := C.git_tree_entrycount(t.cast_ptr)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(t)
|
2013-03-05 13:53:04 -06:00
|
|
|
return uint64(num)
|
|
|
|
}
|
|
|
|
|
|
|
|
type TreeWalkCallback func(string, *TreeEntry) int
|
|
|
|
|
2020-12-05 13:43:02 -06:00
|
|
|
//export treeWalkCallback
|
|
|
|
func treeWalkCallback(_root *C.char, entry *C.git_tree_entry, ptr unsafe.Pointer) C.int {
|
2015-05-22 02:56:21 -05:00
|
|
|
root := C.GoString(_root)
|
2013-03-05 13:53:04 -06:00
|
|
|
|
2015-04-23 03:03:49 -05:00
|
|
|
if callback, ok := pointerHandles.Get(ptr).(TreeWalkCallback); ok {
|
|
|
|
return C.int(callback(root, newTreeEntry(entry)))
|
|
|
|
} else {
|
2015-05-22 01:58:21 -05:00
|
|
|
panic("invalid treewalk callback")
|
2015-04-23 03:03:49 -05:00
|
|
|
}
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
2019-11-17 02:19:36 -06:00
|
|
|
func (t *Tree) Walk(callback TreeWalkCallback) error {
|
2013-09-18 02:23:47 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2015-04-23 03:03:49 -05:00
|
|
|
ptr := pointerHandles.Track(callback)
|
|
|
|
defer pointerHandles.Untrack(ptr)
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
err := C._go_git_treewalk(
|
2014-04-01 05:13:37 -05:00
|
|
|
t.cast_ptr,
|
2013-03-05 13:53:04 -06:00
|
|
|
C.GIT_TREEWALK_PRE,
|
2015-04-23 03:03:49 -05:00
|
|
|
ptr,
|
2013-03-05 13:53:04 -06:00
|
|
|
)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(t)
|
2013-03-05 13:53:04 -06:00
|
|
|
if err < 0 {
|
2013-07-07 09:43:44 -05:00
|
|
|
return MakeGitError(err)
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type TreeBuilder struct {
|
2014-03-07 18:43:20 -06:00
|
|
|
ptr *C.git_treebuilder
|
2013-03-05 13:53:04 -06:00
|
|
|
repo *Repository
|
|
|
|
}
|
|
|
|
|
2013-03-05 18:43:48 -06:00
|
|
|
func (v *TreeBuilder) Free() {
|
|
|
|
runtime.SetFinalizer(v, nil)
|
2013-03-05 13:53:04 -06:00
|
|
|
C.git_treebuilder_free(v.ptr)
|
|
|
|
}
|
|
|
|
|
2016-01-27 11:11:12 -06:00
|
|
|
func (v *TreeBuilder) Insert(filename string, id *Oid, filemode Filemode) error {
|
2013-03-05 13:53:04 -06:00
|
|
|
cfilename := C.CString(filename)
|
|
|
|
defer C.free(unsafe.Pointer(cfilename))
|
|
|
|
|
2013-09-18 02:23:47 -05:00
|
|
|
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))
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
|
|
|
runtime.KeepAlive(id)
|
2013-03-05 13:53:04 -06:00
|
|
|
if err < 0 {
|
2013-07-07 09:43:44 -05:00
|
|
|
return MakeGitError(err)
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-03-07 18:43:20 -06:00
|
|
|
func (v *TreeBuilder) Remove(filename string) error {
|
|
|
|
cfilename := C.CString(filename)
|
|
|
|
defer C.free(unsafe.Pointer(cfilename))
|
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
|
|
|
err := C.git_treebuilder_remove(v.ptr, cfilename)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
2014-03-07 18:43:20 -06:00
|
|
|
if err < 0 {
|
|
|
|
return MakeGitError(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
func (v *TreeBuilder) Write() (*Oid, error) {
|
|
|
|
oid := new(Oid)
|
2013-09-18 02:23:47 -05:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2014-12-18 16:08:11 -06:00
|
|
|
err := C.git_treebuilder_write(oid.toC(), v.ptr)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
2013-03-05 13:53:04 -06:00
|
|
|
if err < 0 {
|
2013-07-07 09:43:44 -05:00
|
|
|
return nil, MakeGitError(err)
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return oid, nil
|
|
|
|
}
|