KeepAlive all the things #393

Merged
carlosmn merged 5 commits from cmn/keepalive-all-the-things into master 2017-07-08 09:51:22 -05:00
17 changed files with 353 additions and 122 deletions
Showing only changes of commit 55a1096141 - Show all commits

View File

@ -18,10 +18,11 @@ import (
type AnnotatedCommit struct { type AnnotatedCommit struct {
ptr *C.git_annotated_commit ptr *C.git_annotated_commit
r *Repository
} }
func newAnnotatedCommitFromC(c *C.git_annotated_commit) *AnnotatedCommit { func newAnnotatedCommitFromC(ptr *C.git_annotated_commit, r *Repository) *AnnotatedCommit {
mh := &AnnotatedCommit{ptr: c} mh := &AnnotatedCommit{ptr: ptr, r: r}
runtime.SetFinalizer(mh, (*AnnotatedCommit).Free) runtime.SetFinalizer(mh, (*AnnotatedCommit).Free)
return mh return mh
} }
@ -32,8 +33,6 @@ func (mh *AnnotatedCommit) Free() {
} }
func (r *Repository) AnnotatedCommitFromFetchHead(branchName string, remoteURL string, oid *Oid) (*AnnotatedCommit, error) { func (r *Repository) AnnotatedCommitFromFetchHead(branchName string, remoteURL string, oid *Oid) (*AnnotatedCommit, error) {
mh := &AnnotatedCommit{}
cbranchName := C.CString(branchName) cbranchName := C.CString(branchName)
defer C.free(unsafe.Pointer(cbranchName)) defer C.free(unsafe.Pointer(cbranchName))
@ -43,40 +42,41 @@ func (r *Repository) AnnotatedCommitFromFetchHead(branchName string, remoteURL s
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_annotated_commit_from_fetchhead(&mh.ptr, r.ptr, cbranchName, cremoteURL, oid.toC()) var ptr *C.git_annotated_commit
ret := C.git_annotated_commit_from_fetchhead(&ptr, r.ptr, cbranchName, cremoteURL, oid.toC())
runtime.KeepAlive(oid)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
runtime.SetFinalizer(mh, (*AnnotatedCommit).Free)
return mh, nil return newAnnotatedCommitFromC(ptr, r), nil
} }
func (r *Repository) LookupAnnotatedCommit(oid *Oid) (*AnnotatedCommit, error) { func (r *Repository) LookupAnnotatedCommit(oid *Oid) (*AnnotatedCommit, error) {
mh := &AnnotatedCommit{}
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_annotated_commit_lookup(&mh.ptr, r.ptr, oid.toC()) var ptr *C.git_annotated_commit
ret := C.git_annotated_commit_lookup(&ptr, r.ptr, oid.toC())
runtime.KeepAlive(oid)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
runtime.SetFinalizer(mh, (*AnnotatedCommit).Free) return newAnnotatedCommitFromC(ptr, r), nil
return mh, nil
} }
func (r *Repository) AnnotatedCommitFromRef(ref *Reference) (*AnnotatedCommit, error) { func (r *Repository) AnnotatedCommitFromRef(ref *Reference) (*AnnotatedCommit, error) {
mh := &AnnotatedCommit{}
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_annotated_commit_from_ref(&mh.ptr, r.ptr, ref.ptr) var ptr *C.git_annotated_commit
ret := C.git_annotated_commit_from_ref(&ptr, r.ptr, ref.ptr)
runtime.KeepAlive(r)
runtime.KeepAlive(ref)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
runtime.SetFinalizer(mh, (*AnnotatedCommit).Free) return newAnnotatedCommitFromC(ptr, r), nil
return mh, nil
} }
type MergeTreeFlag int type MergeTreeFlag int
@ -162,6 +162,7 @@ func (r *Repository) Merge(theirHeads []*AnnotatedCommit, mergeOptions *MergeOpt
} }
ptr := unsafe.Pointer(&gmerge_head_array[0]) ptr := unsafe.Pointer(&gmerge_head_array[0])
err := C.git_merge(r.ptr, (**C.git_annotated_commit)(ptr), C.size_t(len(theirHeads)), cMergeOpts, cCheckoutOpts) err := C.git_merge(r.ptr, (**C.git_annotated_commit)(ptr), C.size_t(len(theirHeads)), cMergeOpts, cCheckoutOpts)
runtime.KeepAlive(theirHeads)
if err < 0 { if err < 0 {
return MakeGitError(err) return MakeGitError(err)
} }
@ -201,6 +202,7 @@ func (r *Repository) MergeAnalysis(theirHeads []*AnnotatedCommit) (MergeAnalysis
var analysis C.git_merge_analysis_t var analysis C.git_merge_analysis_t
var preference C.git_merge_preference_t var preference C.git_merge_preference_t
err := C.git_merge_analysis(&analysis, &preference, r.ptr, (**C.git_annotated_commit)(ptr), C.size_t(len(theirHeads))) err := C.git_merge_analysis(&analysis, &preference, r.ptr, (**C.git_annotated_commit)(ptr), C.size_t(len(theirHeads)))
runtime.KeepAlive(theirHeads)
if err < 0 { if err < 0 {
return MergeAnalysisNone, MergePreferenceNone, MakeGitError(err) return MergeAnalysisNone, MergePreferenceNone, MakeGitError(err)
} }
@ -214,14 +216,15 @@ func (r *Repository) MergeCommits(ours *Commit, theirs *Commit, options *MergeOp
copts := options.toC() copts := options.toC()
idx := &Index{} var ptr *C.git_index
ret := C.git_merge_commits(&ptr, r.ptr, ours.cast_ptr, theirs.cast_ptr, copts)
ret := C.git_merge_commits(&idx.ptr, r.ptr, ours.cast_ptr, theirs.cast_ptr, copts) runtime.KeepAlive(ours)
runtime.KeepAlive(theirs)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
runtime.SetFinalizer(idx, (*Index).Free)
return idx, nil return newIndexFromC(ptr, r), nil
} }
func (r *Repository) MergeTrees(ancestor *Tree, ours *Tree, theirs *Tree, options *MergeOptions) (*Index, error) { func (r *Repository) MergeTrees(ancestor *Tree, ours *Tree, theirs *Tree, options *MergeOptions) (*Index, error) {
@ -230,17 +233,20 @@ func (r *Repository) MergeTrees(ancestor *Tree, ours *Tree, theirs *Tree, option
copts := options.toC() copts := options.toC()
idx := &Index{}
var ancestor_ptr *C.git_tree var ancestor_ptr *C.git_tree
if ancestor != nil { if ancestor != nil {
ancestor_ptr = ancestor.cast_ptr ancestor_ptr = ancestor.cast_ptr
} }
ret := C.git_merge_trees(&idx.ptr, r.ptr, ancestor_ptr, ours.cast_ptr, theirs.cast_ptr, copts) var ptr *C.git_index
ret := C.git_merge_trees(&ptr, r.ptr, ancestor_ptr, ours.cast_ptr, theirs.cast_ptr, copts)
runtime.KeepAlive(ancestor)
runtime.KeepAlive(ours)
runtime.KeepAlive(theirs)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
runtime.SetFinalizer(idx, (*Index).Free)
return idx, nil return newIndexFromC(ptr, r), nil
} }
func (r *Repository) MergeBase(one *Oid, two *Oid) (*Oid, error) { func (r *Repository) MergeBase(one *Oid, two *Oid) (*Oid, error) {
@ -249,6 +255,9 @@ func (r *Repository) MergeBase(one *Oid, two *Oid) (*Oid, error) {
var oid C.git_oid var oid C.git_oid
ret := C.git_merge_base(&oid, r.ptr, one.toC(), two.toC()) ret := C.git_merge_base(&oid, r.ptr, one.toC(), two.toC())
runtime.KeepAlive(one)
runtime.KeepAlive(two)
runtime.KeepAlive(r)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -265,6 +274,8 @@ func (r *Repository) MergeBases(one, two *Oid) ([]*Oid, error) {
var coids C.git_oidarray var coids C.git_oidarray
ret := C.git_merge_bases(&coids, r.ptr, one.toC(), two.toC()) ret := C.git_merge_bases(&coids, r.ptr, one.toC(), two.toC())
runtime.KeepAlive(one)
runtime.KeepAlive(two)
if ret < 0 { if ret < 0 {
return make([]*Oid, 0), MakeGitError(ret) return make([]*Oid, 0), MakeGitError(ret)
} }
@ -413,6 +424,9 @@ func MergeFile(ancestor MergeFileInput, ours MergeFileInput, theirs MergeFileInp
(*C.char)(unsafe.Pointer(oursContents)), C.size_t(len(ours.Contents)), oursPath, C.uint(ours.Mode), (*C.char)(unsafe.Pointer(oursContents)), C.size_t(len(ours.Contents)), oursPath, C.uint(ours.Mode),
(*C.char)(unsafe.Pointer(theirsContents)), C.size_t(len(theirs.Contents)), theirsPath, C.uint(theirs.Mode), (*C.char)(unsafe.Pointer(theirsContents)), C.size_t(len(theirs.Contents)), theirsPath, C.uint(theirs.Mode),
copts) copts)
runtime.KeepAlive(ancestor)
runtime.KeepAlive(ours)
runtime.KeepAlive(theirs)
if ecode < 0 { if ecode < 0 {
return nil, MakeGitError(ecode) return nil, MakeGitError(ecode)
} }

48
note.go
View File

@ -52,7 +52,8 @@ func (c *NoteCollection) Create(
ret := C.git_note_create( ret := C.git_note_create(
oid.toC(), c.repo.ptr, cref, authorSig, oid.toC(), c.repo.ptr, cref, authorSig,
committerSig, id.toC(), cnote, cbool(force)) committerSig, id.toC(), cnote, cbool(force))
runtime.KeepAlive(c)
runtime.KeepAlive(id)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -69,17 +70,18 @@ func (c *NoteCollection) Read(ref string, id *Oid) (*Note, error) {
defer C.free(unsafe.Pointer(cref)) defer C.free(unsafe.Pointer(cref))
} }
note := new(Note)
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
if ret := C.git_note_read(&note.ptr, c.repo.ptr, cref, id.toC()); ret < 0 { var ptr *C.git_note
ret := C.git_note_read(&ptr, c.repo.ptr, cref, id.toC())
runtime.KeepAlive(c)
runtime.KeepAlive(id)
if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
runtime.SetFinalizer(note, (*Note).Free) return newNoteFromC(ptr, c.repo), nil
return note, nil
} }
// Remove removes the note for an object // Remove removes the note for an object
@ -108,6 +110,8 @@ func (c *NoteCollection) Remove(ref string, author, committer *Signature, id *Oi
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_note_remove(c.repo.ptr, cref, authorSig, committerSig, id.toC()) ret := C.git_note_remove(c.repo.ptr, cref, authorSig, committerSig, id.toC())
runtime.KeepAlive(c)
runtime.KeepAlive(id)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -121,8 +125,10 @@ func (c *NoteCollection) DefaultRef() (string, error) {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
if ret := C.git_note_default_ref(&buf, c.repo.ptr); ret < 0 { ecode := C.git_note_default_ref(&buf, c.repo.ptr)
return "", MakeGitError(ret) runtime.KeepAlive(c)
if ecode < 0 {
return "", MakeGitError(ecode)
} }
ret := C.GoString(buf.ptr) ret := C.GoString(buf.ptr)
@ -134,6 +140,13 @@ func (c *NoteCollection) DefaultRef() (string, error) {
// Note // Note
type Note struct { type Note struct {
ptr *C.git_note ptr *C.git_note
r *Repository
}
func newNoteFromC(ptr *C.git_note, r *Repository) *Note {
note := &Note{ptr: ptr, r: r}
runtime.SetFinalizer(note, (*Note).Free)
return note
} }
// Free frees a git_note object // Free frees a git_note object
@ -156,23 +169,28 @@ func (n *Note) Author() *Signature {
// Id returns the note object's id // Id returns the note object's id
func (n *Note) Id() *Oid { func (n *Note) Id() *Oid {
ptr := C.git_note_id(n.ptr) ptr := C.git_note_id(n.ptr)
runtime.KeepAlive(n)
return newOidFromC(ptr) return newOidFromC(ptr)
} }
// Committer returns the signature of the note committer // Committer returns the signature of the note committer
func (n *Note) Committer() *Signature { func (n *Note) Committer() *Signature {
ptr := C.git_note_committer(n.ptr) ptr := C.git_note_committer(n.ptr)
runtime.KeepAlive(n)
return newSignatureFromC(ptr) return newSignatureFromC(ptr)
} }
// Message returns the note message // Message returns the note message
func (n *Note) Message() string { func (n *Note) Message() string {
return C.GoString(C.git_note_message(n.ptr)) ret := C.GoString(C.git_note_message(n.ptr))
runtime.KeepAlive(n)
return ret
} }
// NoteIterator // NoteIterator
type NoteIterator struct { type NoteIterator struct {
ptr *C.git_note_iterator ptr *C.git_note_iterator
r *Repository
} }
// NewNoteIterator creates a new iterator for notes // NewNoteIterator creates a new iterator for notes
@ -190,11 +208,13 @@ func (repo *Repository) NewNoteIterator(ref string) (*NoteIterator, error) {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
if ret := C.git_note_iterator_new(&ptr, repo.ptr, cref); ret < 0 { ret := C.git_note_iterator_new(&ptr, repo.ptr, cref)
runtime.KeepAlive(repo)
if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
iter := &NoteIterator{ptr: ptr} iter := &NoteIterator{ptr: ptr, r: repo}
runtime.SetFinalizer(iter, (*NoteIterator).Free) runtime.SetFinalizer(iter, (*NoteIterator).Free)
return iter, nil return iter, nil
} }
@ -213,7 +233,11 @@ func (it *NoteIterator) Next() (noteId, annotatedId *Oid, err error) {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
if ret := C.git_note_next(noteId.toC(), annotatedId.toC(), it.ptr); ret < 0 { ret := C.git_note_next(noteId.toC(), annotatedId.toC(), it.ptr)
runtime.KeepAlive(noteId)
runtime.KeepAlive(annotatedId)
runtime.KeepAlive(it)
if ret < 0 {
err = MakeGitError(ret) err = MakeGitError(ret)
} }
return return

View File

@ -46,7 +46,9 @@ func (t ObjectType) String() string {
} }
func (o *Object) Id() *Oid { func (o *Object) Id() *Oid {
return newOidFromC(C.git_object_id(o.ptr)) ret := newOidFromC(C.git_object_id(o.ptr))
runtime.KeepAlive(o)
return ret
} }
func (o *Object) ShortId() (string, error) { func (o *Object) ShortId() (string, error) {
@ -56,6 +58,7 @@ func (o *Object) ShortId() (string, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ecode := C.git_object_short_id(&resultBuf, o.ptr) ecode := C.git_object_short_id(&resultBuf, o.ptr)
runtime.KeepAlive(o)
if ecode < 0 { if ecode < 0 {
return "", MakeGitError(ecode) return "", MakeGitError(ecode)
} }
@ -64,15 +67,19 @@ func (o *Object) ShortId() (string, error) {
} }
func (o *Object) Type() ObjectType { func (o *Object) Type() ObjectType {
return ObjectType(C.git_object_type(o.ptr)) ret := ObjectType(C.git_object_type(o.ptr))
runtime.KeepAlive(o)
return ret
} }
// Owner returns a weak reference to the repository which owns this // Owner returns a weak reference to the repository which owns this
// object. This won't keep the underlying repository alive. // object. This won't keep the underlying repository alive.
func (o *Object) Owner() *Repository { func (o *Object) Owner() *Repository {
return &Repository{ ret := &Repository{
ptr: C.git_object_owner(o.ptr), ptr: C.git_object_owner(o.ptr),
} }
runtime.KeepAlive(o)
return ret
} }
func dupObject(obj *Object, kind ObjectType) (*C.git_object, error) { func dupObject(obj *Object, kind ObjectType) (*C.git_object, error) {
@ -85,7 +92,9 @@ func dupObject(obj *Object, kind ObjectType) (*C.git_object, error) {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
if err := C.git_object_dup(&cobj, obj.ptr); err < 0 { err := C.git_object_dup(&cobj, obj.ptr)
runtime.KeepAlive(obj)
if err < 0 {
return nil, MakeGitError(err) return nil, MakeGitError(err)
} }
@ -203,7 +212,9 @@ func (o *Object) Peel(t ObjectType) (*Object, error) {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
if err := C.git_object_peel(&cobj, o.ptr, C.git_otype(t)); err < 0 { err := C.git_object_peel(&cobj, o.ptr, C.git_otype(t))
runtime.KeepAlive(o)
if err < 0 {
return nil, MakeGitError(err) return nil, MakeGitError(err)
} }

30
odb.go
View File

@ -47,6 +47,7 @@ func (v *Odb) AddBackend(backend *OdbBackend, priority int) (err error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_odb_add_backend(v.ptr, backend.ptr, C.int(priority)) ret := C.git_odb_add_backend(v.ptr, backend.ptr, C.int(priority))
runtime.KeepAlive(v)
if ret < 0 { if ret < 0 {
backend.Free() backend.Free()
return MakeGitError(ret) return MakeGitError(ret)
@ -62,6 +63,7 @@ func (v *Odb) ReadHeader(oid *Oid) (uint64, ObjectType, error) {
var cotype C.git_otype var cotype C.git_otype
ret := C.git_odb_read_header(&sz, &cotype, v.ptr, oid.toC()) ret := C.git_odb_read_header(&sz, &cotype, v.ptr, oid.toC())
runtime.KeepAlive(v)
if ret < 0 { if ret < 0 {
return 0, C.GIT_OBJ_BAD, MakeGitError(ret) return 0, C.GIT_OBJ_BAD, MakeGitError(ret)
} }
@ -71,6 +73,8 @@ func (v *Odb) ReadHeader(oid *Oid) (uint64, ObjectType, error) {
func (v *Odb) Exists(oid *Oid) bool { func (v *Odb) Exists(oid *Oid) bool {
ret := C.git_odb_exists(v.ptr, oid.toC()) ret := C.git_odb_exists(v.ptr, oid.toC())
runtime.KeepAlive(v)
runtime.KeepAlive(oid)
return ret != 0 return ret != 0
} }
@ -85,7 +89,7 @@ func (v *Odb) Write(data []byte, otype ObjectType) (oid *Oid, err error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_odb_write(oid.toC(), v.ptr, cptr, C.size_t(len(data)), C.git_otype(otype)) ret := C.git_odb_write(oid.toC(), v.ptr, cptr, C.size_t(len(data)), C.git_otype(otype))
runtime.KeepAlive(v)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -100,6 +104,8 @@ func (v *Odb) Read(oid *Oid) (obj *OdbObject, err error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_odb_read(&obj.ptr, v.ptr, oid.toC()) ret := C.git_odb_read(&obj.ptr, v.ptr, oid.toC())
runtime.KeepAlive(v)
runtime.KeepAlive(oid)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -145,6 +151,7 @@ func (v *Odb) ForEach(callback OdbForEachCallback) error {
defer pointerHandles.Untrack(handle) defer pointerHandles.Untrack(handle)
ret := C._go_git_odb_foreach(v.ptr, handle) ret := C._go_git_odb_foreach(v.ptr, handle)
runtime.KeepAlive(v)
if ret == C.GIT_EUSER { if ret == C.GIT_EUSER {
return data.err return data.err
} else if ret < 0 { } else if ret < 0 {
@ -164,6 +171,7 @@ func (v *Odb) Hash(data []byte, otype ObjectType) (oid *Oid, err error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_odb_hash(oid.toC(), ptr, C.size_t(header.Len), C.git_otype(otype)) ret := C.git_odb_hash(oid.toC(), ptr, C.size_t(header.Len), C.git_otype(otype))
runtime.KeepAlive(data)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -179,6 +187,8 @@ func (v *Odb) NewReadStream(id *Oid) (*OdbReadStream, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_odb_open_rstream(&stream.ptr, v.ptr, id.toC()) ret := C.git_odb_open_rstream(&stream.ptr, v.ptr, id.toC())
runtime.KeepAlive(v)
runtime.KeepAlive(id)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -197,6 +207,7 @@ func (v *Odb) NewWriteStream(size int64, otype ObjectType) (*OdbWriteStream, err
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_odb_open_wstream(&stream.ptr, v.ptr, C.git_off_t(size), C.git_otype(otype)) ret := C.git_odb_open_wstream(&stream.ptr, v.ptr, C.git_off_t(size), C.git_otype(otype))
runtime.KeepAlive(v)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -219,17 +230,25 @@ func (v *OdbObject) Free() {
} }
func (object *OdbObject) Id() (oid *Oid) { func (object *OdbObject) Id() (oid *Oid) {
return newOidFromC(C.git_odb_object_id(object.ptr)) ret := newOidFromC(C.git_odb_object_id(object.ptr))
runtime.KeepAlive(object)
return ret
} }
func (object *OdbObject) Len() (len uint64) { func (object *OdbObject) Len() (len uint64) {
return uint64(C.git_odb_object_size(object.ptr)) ret := uint64(C.git_odb_object_size(object.ptr))
runtime.KeepAlive(object)
return ret
} }
func (object *OdbObject) Type() ObjectType { func (object *OdbObject) Type() ObjectType {
return ObjectType(C.git_odb_object_type(object.ptr)) ret := ObjectType(C.git_odb_object_type(object.ptr))
runtime.KeepAlive(object)
return ret
} }
// Data returns a slice pointing to the unmanaged object memory. You must make
// sure the object is referenced for at least as long as the slice is used.
func (object *OdbObject) Data() (data []byte) { func (object *OdbObject) Data() (data []byte) {
var c_blob unsafe.Pointer = C.git_odb_object_data(object.ptr) var c_blob unsafe.Pointer = C.git_odb_object_data(object.ptr)
var blob []byte var blob []byte
@ -258,6 +277,7 @@ func (stream *OdbReadStream) Read(data []byte) (int, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_odb_stream_read(stream.ptr, ptr, size) ret := C.git_odb_stream_read(stream.ptr, ptr, size)
runtime.KeepAlive(stream)
if ret < 0 { if ret < 0 {
return 0, MakeGitError(ret) return 0, MakeGitError(ret)
} }
@ -293,6 +313,7 @@ func (stream *OdbWriteStream) Write(data []byte) (int, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_odb_stream_write(stream.ptr, ptr, size) ret := C.git_odb_stream_write(stream.ptr, ptr, size)
runtime.KeepAlive(stream)
if ret < 0 { if ret < 0 {
return 0, MakeGitError(ret) return 0, MakeGitError(ret)
} }
@ -307,6 +328,7 @@ func (stream *OdbWriteStream) Close() error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_odb_stream_finalize_write(stream.Id.toC(), stream.ptr) ret := C.git_odb_stream_finalize_write(stream.Id.toC(), stream.ptr)
runtime.KeepAlive(stream)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }

View File

@ -17,20 +17,25 @@ import (
type Packbuilder struct { type Packbuilder struct {
ptr *C.git_packbuilder ptr *C.git_packbuilder
r *Repository
} }
func (repo *Repository) NewPackbuilder() (*Packbuilder, error) { func (repo *Repository) NewPackbuilder() (*Packbuilder, error) {
builder := &Packbuilder{}
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_packbuilder_new(&builder.ptr, repo.ptr) var ptr *C.git_packbuilder
ret := C.git_packbuilder_new(&ptr, repo.ptr)
if ret != 0 { if ret != 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
runtime.SetFinalizer(builder, (*Packbuilder).Free) return newPackbuilderFromC(ptr, repo), nil
return builder, nil }
func newPackbuilderFromC(ptr *C.git_packbuilder, r *Repository) *Packbuilder {
pb := &Packbuilder{ptr: ptr, r: r}
runtime.SetFinalizer(pb, (*Packbuilder).Free)
return pb
} }
func (pb *Packbuilder) Free() { func (pb *Packbuilder) Free() {
@ -46,6 +51,8 @@ func (pb *Packbuilder) Insert(id *Oid, name string) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_packbuilder_insert(pb.ptr, id.toC(), cname) ret := C.git_packbuilder_insert(pb.ptr, id.toC(), cname)
runtime.KeepAlive(pb)
runtime.KeepAlive(id)
if ret != 0 { if ret != 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -57,6 +64,8 @@ func (pb *Packbuilder) InsertCommit(id *Oid) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_packbuilder_insert_commit(pb.ptr, id.toC()) ret := C.git_packbuilder_insert_commit(pb.ptr, id.toC())
runtime.KeepAlive(pb)
runtime.KeepAlive(id)
if ret != 0 { if ret != 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -68,6 +77,8 @@ func (pb *Packbuilder) InsertTree(id *Oid) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_packbuilder_insert_tree(pb.ptr, id.toC()) ret := C.git_packbuilder_insert_tree(pb.ptr, id.toC())
runtime.KeepAlive(pb)
runtime.KeepAlive(id)
if ret != 0 { if ret != 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -75,7 +86,9 @@ func (pb *Packbuilder) InsertTree(id *Oid) error {
} }
func (pb *Packbuilder) ObjectCount() uint32 { func (pb *Packbuilder) ObjectCount() uint32 {
return uint32(C.git_packbuilder_object_count(pb.ptr)) ret := uint32(C.git_packbuilder_object_count(pb.ptr))
runtime.KeepAlive(pb)
return ret
} }
func (pb *Packbuilder) WriteToFile(name string, mode os.FileMode) error { func (pb *Packbuilder) WriteToFile(name string, mode os.FileMode) error {
@ -86,6 +99,7 @@ func (pb *Packbuilder) WriteToFile(name string, mode os.FileMode) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_packbuilder_write(pb.ptr, cname, C.uint(mode.Perm()), nil, nil) ret := C.git_packbuilder_write(pb.ptr, cname, C.uint(mode.Perm()), nil, nil)
runtime.KeepAlive(pb)
if ret != 0 { if ret != 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -100,7 +114,9 @@ func (pb *Packbuilder) Write(w io.Writer) error {
} }
func (pb *Packbuilder) Written() uint32 { func (pb *Packbuilder) Written() uint32 {
return uint32(C.git_packbuilder_written(pb.ptr)) ret := uint32(C.git_packbuilder_written(pb.ptr))
runtime.KeepAlive(pb)
return ret
} }
type PackbuilderForeachCallback func([]byte) error type PackbuilderForeachCallback func([]byte) error
@ -142,6 +158,7 @@ func (pb *Packbuilder) ForEach(callback PackbuilderForeachCallback) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
err := C._go_git_packbuilder_foreach(pb.ptr, handle) err := C._go_git_packbuilder_foreach(pb.ptr, handle)
runtime.KeepAlive(pb)
if err == C.GIT_EUSER { if err == C.GIT_EUSER {
return data.err return data.err
} }

View File

@ -47,6 +47,7 @@ func (patch *Patch) String() (string, error) {
var buf C.git_buf var buf C.git_buf
ecode := C.git_patch_to_buf(&buf, patch.ptr) ecode := C.git_patch_to_buf(&buf, patch.ptr)
runtime.KeepAlive(patch)
if ecode < 0 { if ecode < 0 {
return "", MakeGitError(ecode) return "", MakeGitError(ecode)
} }
@ -83,6 +84,8 @@ func (v *Repository) PatchFromBuffers(oldPath, newPath string, oldBuf, newBuf []
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ecode := C.git_patch_from_buffers(&patchPtr, oldPtr, C.size_t(len(oldBuf)), cOldPath, newPtr, C.size_t(len(newBuf)), cNewPath, copts) ecode := C.git_patch_from_buffers(&patchPtr, oldPtr, C.size_t(len(oldBuf)), cOldPath, newPtr, C.size_t(len(newBuf)), cNewPath, copts)
runtime.KeepAlive(oldBuf)
runtime.KeepAlive(newBuf)
if ecode < 0 { if ecode < 0 {
return nil, MakeGitError(ecode) return nil, MakeGitError(ecode)
} }

View File

@ -100,6 +100,7 @@ func mapEmptyStringToNull(ref string) *C.char {
// Rebase is the struct representing a Rebase object. // Rebase is the struct representing a Rebase object.
type Rebase struct { type Rebase struct {
ptr *C.git_rebase ptr *C.git_rebase
r *Repository
} }
// InitRebase initializes a rebase operation to rebase the changes in branch relative to upstream onto another branch. // InitRebase initializes a rebase operation to rebase the changes in branch relative to upstream onto another branch.
@ -121,6 +122,9 @@ func (r *Repository) InitRebase(branch *AnnotatedCommit, upstream *AnnotatedComm
var ptr *C.git_rebase var ptr *C.git_rebase
err := C.git_rebase_init(&ptr, r.ptr, branch.ptr, upstream.ptr, onto.ptr, opts.toC()) err := C.git_rebase_init(&ptr, r.ptr, branch.ptr, upstream.ptr, onto.ptr, opts.toC())
runtime.KeepAlive(branch)
runtime.KeepAlive(upstream)
runtime.KeepAlive(onto)
if err < 0 { if err < 0 {
return nil, MakeGitError(err) return nil, MakeGitError(err)
} }
@ -135,6 +139,7 @@ func (r *Repository) OpenRebase(opts *RebaseOptions) (*Rebase, error) {
var ptr *C.git_rebase var ptr *C.git_rebase
err := C.git_rebase_open(&ptr, r.ptr, opts.toC()) err := C.git_rebase_open(&ptr, r.ptr, opts.toC())
runtime.KeepAlive(r)
if err < 0 { if err < 0 {
return nil, MakeGitError(err) return nil, MakeGitError(err)
} }
@ -165,7 +170,9 @@ func (rebase *Rebase) CurrentOperationIndex() (uint, error) {
// OperationCount gets the count of rebase operations that are to be applied. // OperationCount gets the count of rebase operations that are to be applied.
func (rebase *Rebase) OperationCount() uint { func (rebase *Rebase) OperationCount() uint {
return uint(C.git_rebase_operation_entrycount(rebase.ptr)) ret := uint(C.git_rebase_operation_entrycount(rebase.ptr))
runtime.KeepAlive(rebase)
return ret
} }
// Next performs the next rebase operation and returns the information about it. // Next performs the next rebase operation and returns the information about it.
@ -178,6 +185,7 @@ func (rebase *Rebase) Next() (*RebaseOperation, error) {
var ptr *C.git_rebase_operation var ptr *C.git_rebase_operation
err := C.git_rebase_next(&ptr, rebase.ptr) err := C.git_rebase_next(&ptr, rebase.ptr)
runtime.KeepAlive(rebase)
if err < 0 { if err < 0 {
return nil, MakeGitError(err) return nil, MakeGitError(err)
} }
@ -207,6 +215,8 @@ func (rebase *Rebase) Commit(ID *Oid, author, committer *Signature, message stri
defer C.free(unsafe.Pointer(cmsg)) defer C.free(unsafe.Pointer(cmsg))
cerr := C.git_rebase_commit(ID.toC(), rebase.ptr, authorSig, committerSig, nil, cmsg) cerr := C.git_rebase_commit(ID.toC(), rebase.ptr, authorSig, committerSig, nil, cmsg)
runtime.KeepAlive(ID)
runtime.KeepAlive(rebase)
if cerr < 0 { if cerr < 0 {
return MakeGitError(cerr) return MakeGitError(cerr)
} }
@ -220,6 +230,7 @@ func (rebase *Rebase) Finish() error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
err := C.git_rebase_finish(rebase.ptr, nil) err := C.git_rebase_finish(rebase.ptr, nil)
runtime.KeepAlive(rebase)
if err < 0 { if err < 0 {
return MakeGitError(err) return MakeGitError(err)
} }
@ -233,6 +244,7 @@ func (rebase *Rebase) Abort() error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
err := C.git_rebase_abort(rebase.ptr) err := C.git_rebase_abort(rebase.ptr)
runtime.KeepAlive(rebase)
if err < 0 { if err < 0 {
return MakeGitError(err) return MakeGitError(err)
} }

View File

@ -14,6 +14,7 @@ import (
type Refdb struct { type Refdb struct {
ptr *C.git_refdb ptr *C.git_refdb
r *Repository
} }
type RefdbBackend struct { type RefdbBackend struct {
@ -21,16 +22,17 @@ type RefdbBackend struct {
} }
func (v *Repository) NewRefdb() (refdb *Refdb, err error) { func (v *Repository) NewRefdb() (refdb *Refdb, err error) {
refdb = new(Refdb) var ptr *C.git_refdb
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_refdb_new(&refdb.ptr, v.ptr) ret := C.git_refdb_new(&ptr, v.ptr)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
refdb = &Refdb{ptr: ptr, r: v}
runtime.SetFinalizer(refdb, (*Refdb).Free) runtime.SetFinalizer(refdb, (*Refdb).Free)
return refdb, nil return refdb, nil
} }
@ -45,6 +47,8 @@ func (v *Refdb) SetBackend(backend *RefdbBackend) (err error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_refdb_set_backend(v.ptr, backend.ptr) ret := C.git_refdb_set_backend(v.ptr, backend.ptr)
runtime.KeepAlive(v)
runtime.KeepAlive(backend)
if ret < 0 { if ret < 0 {
backend.Free() backend.Free()
return MakeGitError(ret) return MakeGitError(ret)
@ -53,5 +57,6 @@ func (v *Refdb) SetBackend(backend *RefdbBackend) (err error) {
} }
func (v *RefdbBackend) Free() { func (v *RefdbBackend) Free() {
runtime.SetFinalizer(v, nil)
C._go_git_refdb_backend_free(v.ptr) C._go_git_refdb_backend_free(v.ptr)
} }

View File

@ -34,6 +34,7 @@ func (c *ReferenceCollection) Lookup(name string) (*Reference, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ecode := C.git_reference_lookup(&ptr, c.repo.ptr, cname) ecode := C.git_reference_lookup(&ptr, c.repo.ptr, cname)
runtime.KeepAlive(c)
if ecode < 0 { if ecode < 0 {
return nil, MakeGitError(ecode) return nil, MakeGitError(ecode)
} }
@ -59,6 +60,8 @@ func (c *ReferenceCollection) Create(name string, id *Oid, force bool, msg strin
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ecode := C.git_reference_create(&ptr, c.repo.ptr, cname, id.toC(), cbool(force), cmsg) ecode := C.git_reference_create(&ptr, c.repo.ptr, cname, id.toC(), cbool(force), cmsg)
runtime.KeepAlive(c)
runtime.KeepAlive(id)
if ecode < 0 { if ecode < 0 {
return nil, MakeGitError(ecode) return nil, MakeGitError(ecode)
} }
@ -87,6 +90,7 @@ func (c *ReferenceCollection) CreateSymbolic(name, target string, force bool, ms
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ecode := C.git_reference_symbolic_create(&ptr, c.repo.ptr, cname, ctarget, cbool(force), cmsg) ecode := C.git_reference_symbolic_create(&ptr, c.repo.ptr, cname, ctarget, cbool(force), cmsg)
runtime.KeepAlive(c)
if ecode < 0 { if ecode < 0 {
return nil, MakeGitError(ecode) return nil, MakeGitError(ecode)
} }
@ -104,6 +108,7 @@ func (c *ReferenceCollection) EnsureLog(name string) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_reference_ensure_log(c.repo.ptr, cname) ret := C.git_reference_ensure_log(c.repo.ptr, cname)
runtime.KeepAlive(c)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -121,6 +126,7 @@ func (c *ReferenceCollection) HasLog(name string) (bool, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_reference_has_log(c.repo.ptr, cname) ret := C.git_reference_has_log(c.repo.ptr, cname)
runtime.KeepAlive(c)
if ret < 0 { if ret < 0 {
return false, MakeGitError(ret) return false, MakeGitError(ret)
} }
@ -138,6 +144,7 @@ func (c *ReferenceCollection) Dwim(name string) (*Reference, error) {
var ptr *C.git_reference var ptr *C.git_reference
ret := C.git_reference_dwim(&ptr, c.repo.ptr, cname) ret := C.git_reference_dwim(&ptr, c.repo.ptr, cname)
runtime.KeepAlive(c)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -169,6 +176,7 @@ func (v *Reference) SetSymbolicTarget(target string, msg string) (*Reference, er
} }
ret := C.git_reference_symbolic_set_target(&ptr, v.ptr, ctarget, cmsg) ret := C.git_reference_symbolic_set_target(&ptr, v.ptr, ctarget, cmsg)
runtime.KeepAlive(v)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -191,6 +199,7 @@ func (v *Reference) SetTarget(target *Oid, msg string) (*Reference, error) {
} }
ret := C.git_reference_set_target(&ptr, v.ptr, target.toC(), cmsg) ret := C.git_reference_set_target(&ptr, v.ptr, target.toC(), cmsg)
runtime.KeepAlive(v)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -205,6 +214,7 @@ func (v *Reference) Resolve() (*Reference, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_reference_resolve(&ptr, v.ptr) ret := C.git_reference_resolve(&ptr, v.ptr)
runtime.KeepAlive(v)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -229,7 +239,7 @@ func (v *Reference) Rename(name string, force bool, msg string) (*Reference, err
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_reference_rename(&ptr, v.ptr, cname, cbool(force), cmsg) ret := C.git_reference_rename(&ptr, v.ptr, cname, cbool(force), cmsg)
runtime.KeepAlive(v)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -238,16 +248,21 @@ func (v *Reference) Rename(name string, force bool, msg string) (*Reference, err
} }
func (v *Reference) Target() *Oid { func (v *Reference) Target() *Oid {
return newOidFromC(C.git_reference_target(v.ptr)) ret := newOidFromC(C.git_reference_target(v.ptr))
runtime.KeepAlive(v)
return ret
} }
func (v *Reference) SymbolicTarget() string { func (v *Reference) SymbolicTarget() string {
var ret string
cstr := C.git_reference_symbolic_target(v.ptr) cstr := C.git_reference_symbolic_target(v.ptr)
if cstr == nil {
return "" if cstr != nil {
return C.GoString(cstr)
} }
return C.GoString(cstr) runtime.KeepAlive(v)
return ret
} }
func (v *Reference) Delete() error { func (v *Reference) Delete() error {
@ -255,7 +270,7 @@ func (v *Reference) Delete() error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_reference_delete(v.ptr) ret := C.git_reference_delete(v.ptr)
runtime.KeepAlive(v)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -269,7 +284,9 @@ func (v *Reference) Peel(t ObjectType) (*Object, error) {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
if err := C.git_reference_peel(&cobj, v.ptr, C.git_otype(t)); err < 0 { err := C.git_reference_peel(&cobj, v.ptr, C.git_otype(t))
runtime.KeepAlive(v)
if err < 0 {
return nil, MakeGitError(err) return nil, MakeGitError(err)
} }
@ -287,37 +304,54 @@ func (v *Reference) Owner() *Repository {
// Cmp compares both references, retursn 0 on equality, otherwise a // Cmp compares both references, retursn 0 on equality, otherwise a
// stable sorting. // stable sorting.
func (v *Reference) Cmp(ref2 *Reference) int { func (v *Reference) Cmp(ref2 *Reference) int {
return int(C.git_reference_cmp(v.ptr, ref2.ptr)) ret := int(C.git_reference_cmp(v.ptr, ref2.ptr))
runtime.KeepAlive(v)
runtime.KeepAlive(ref2)
return ret
} }
// Shorthand returns a "human-readable" short reference name // Shorthand ret :=s a "human-readable" short reference name
func (v *Reference) Shorthand() string { func (v *Reference) Shorthand() string {
return C.GoString(C.git_reference_shorthand(v.ptr)) ret := C.GoString(C.git_reference_shorthand(v.ptr))
runtime.KeepAlive(v)
return ret
} }
func (v *Reference) Name() string { func (v *Reference) Name() string {
return C.GoString(C.git_reference_name(v.ptr)) ret := C.GoString(C.git_reference_name(v.ptr))
runtime.KeepAlive(v)
return ret
} }
func (v *Reference) Type() ReferenceType { func (v *Reference) Type() ReferenceType {
return ReferenceType(C.git_reference_type(v.ptr)) ret := ReferenceType(C.git_reference_type(v.ptr))
runtime.KeepAlive(v)
return ret
} }
func (v *Reference) IsBranch() bool { func (v *Reference) IsBranch() bool {
return C.git_reference_is_branch(v.ptr) == 1 ret := C.git_reference_is_branch(v.ptr) == 1
runtime.KeepAlive(v)
return ret
} }
func (v *Reference) IsRemote() bool { func (v *Reference) IsRemote() bool {
return C.git_reference_is_remote(v.ptr) == 1 ret := C.git_reference_is_remote(v.ptr) == 1
runtime.KeepAlive(v)
return ret
} }
func (v *Reference) IsTag() bool { func (v *Reference) IsTag() bool {
return C.git_reference_is_tag(v.ptr) == 1 ret := C.git_reference_is_tag(v.ptr) == 1
runtime.KeepAlive(v)
return ret
} }
// IsNote checks if the reference is a note. // IsNote checks if the reference is a note.
func (v *Reference) IsNote() bool { func (v *Reference) IsNote() bool {
return C.git_reference_is_note(v.ptr) == 1 ret := C.git_reference_is_note(v.ptr) == 1
runtime.KeepAlive(v)
return ret
} }
func (v *Reference) Free() { func (v *Reference) Free() {
@ -346,9 +380,7 @@ func (repo *Repository) NewReferenceIterator() (*ReferenceIterator, error) {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
iter := &ReferenceIterator{ptr: ptr, repo: repo} return newReferenceIteratorFromC(ptr, repo), nil
runtime.SetFinalizer(iter, (*ReferenceIterator).Free)
return iter, nil
} }
// NewReferenceIterator creates a new branch iterator over reference names // NewReferenceIterator creates a new branch iterator over reference names
@ -363,8 +395,7 @@ func (repo *Repository) NewReferenceNameIterator() (*ReferenceNameIterator, erro
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
iter := &ReferenceIterator{ptr: ptr, repo: repo} iter := newReferenceIteratorFromC(ptr, repo)
runtime.SetFinalizer(iter, (*ReferenceIterator).Free)
return iter.Names(), nil return iter.Names(), nil
} }
@ -384,9 +415,7 @@ func (repo *Repository) NewReferenceIteratorGlob(glob string) (*ReferenceIterato
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
iter := &ReferenceIterator{ptr: ptr} return newReferenceIteratorFromC(ptr, repo), nil
runtime.SetFinalizer(iter, (*ReferenceIterator).Free)
return iter, nil
} }
func (i *ReferenceIterator) Names() *ReferenceNameIterator { func (i *ReferenceIterator) Names() *ReferenceNameIterator {
@ -425,6 +454,13 @@ func (v *ReferenceIterator) Next() (*Reference, error) {
return newReferenceFromC(ptr, v.repo), nil return newReferenceFromC(ptr, v.repo), nil
} }
func newReferenceIteratorFromC(ptr *C.git_reference_iterator, r *Repository) *ReferenceIterator {
return &ReferenceIterator{
ptr: ptr,
repo: r,
}
}
// Free the reference iterator // Free the reference iterator
func (v *ReferenceIterator) Free() { func (v *ReferenceIterator) Free() {
runtime.SetFinalizer(v, nil) runtime.SetFinalizer(v, nil)

View File

@ -120,6 +120,7 @@ func NewRepositoryWrapOdb(odb *Odb) (repo *Repository, err error) {
var ptr *C.git_repository var ptr *C.git_repository
ret := C.git_repository_wrap_odb(&ptr, odb.ptr) ret := C.git_repository_wrap_odb(&ptr, odb.ptr)
runtime.KeepAlive(odb)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }

View File

@ -63,6 +63,7 @@ func (repo *Repository) DefaultSignature() (*Signature, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
cErr := C.git_signature_default(&out, repo.ptr) cErr := C.git_signature_default(&out, repo.ptr)
runtime.KeepAlive(repo)
if cErr < 0 { if cErr < 0 {
return nil, MakeGitError(cErr) return nil, MakeGitError(cErr)
} }

View File

@ -63,7 +63,7 @@ func (c *StashCollection) Save(
ret := C.git_stash_save( ret := C.git_stash_save(
oid.toC(), c.repo.ptr, oid.toC(), c.repo.ptr,
stasherC, messageC, C.uint32_t(flags)) stasherC, messageC, C.uint32_t(flags))
runtime.KeepAlive(c)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -228,6 +228,7 @@ func (c *StashCollection) Apply(index int, opts StashApplyOptions) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_stash_apply(c.repo.ptr, C.size_t(index), optsC) ret := C.git_stash_apply(c.repo.ptr, C.size_t(index), optsC)
runtime.KeepAlive(c)
if ret == C.GIT_EUSER { if ret == C.GIT_EUSER {
return progressData.Error return progressData.Error
} }
@ -282,6 +283,7 @@ func (c *StashCollection) Foreach(callback StashCallback) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C._go_git_stash_foreach(c.repo.ptr, handle) ret := C._go_git_stash_foreach(c.repo.ptr, handle)
runtime.KeepAlive(c)
if ret == C.GIT_EUSER { if ret == C.GIT_EUSER {
return data.Error return data.Error
} }
@ -303,6 +305,7 @@ func (c *StashCollection) Drop(index int) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_stash_drop(c.repo.ptr, C.size_t(index)) ret := C.git_stash_drop(c.repo.ptr, C.size_t(index))
runtime.KeepAlive(c)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -328,6 +331,7 @@ func (c *StashCollection) Pop(index int, opts StashApplyOptions) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_stash_pop(c.repo.ptr, C.size_t(index), optsC) ret := C.git_stash_pop(c.repo.ptr, C.size_t(index), optsC)
runtime.KeepAlive(c)
if ret == C.GIT_EUSER { if ret == C.GIT_EUSER {
return progressData.Error return progressData.Error
} }

View File

@ -55,15 +55,17 @@ func statusEntryFromC(statusEntry *C.git_status_entry) StatusEntry {
type StatusList struct { type StatusList struct {
ptr *C.git_status_list ptr *C.git_status_list
r *Repository
} }
func newStatusListFromC(ptr *C.git_status_list) *StatusList { func newStatusListFromC(ptr *C.git_status_list, r *Repository) *StatusList {
if ptr == nil { if ptr == nil {
return nil return nil
} }
statusList := &StatusList{ statusList := &StatusList{
ptr: ptr, ptr: ptr,
r: r,
} }
runtime.SetFinalizer(statusList, (*StatusList).Free) runtime.SetFinalizer(statusList, (*StatusList).Free)
@ -84,14 +86,20 @@ func (statusList *StatusList) ByIndex(index int) (StatusEntry, error) {
return StatusEntry{}, ErrInvalid return StatusEntry{}, ErrInvalid
} }
ptr := C.git_status_byindex(statusList.ptr, C.size_t(index)) ptr := C.git_status_byindex(statusList.ptr, C.size_t(index))
return statusEntryFromC(ptr), nil entry := statusEntryFromC(ptr)
runtime.KeepAlive(statusList)
return entry, nil
} }
func (statusList *StatusList) EntryCount() (int, error) { func (statusList *StatusList) EntryCount() (int, error) {
if statusList.ptr == nil { if statusList.ptr == nil {
return -1, ErrInvalid return -1, ErrInvalid
} }
return int(C.git_status_list_entrycount(statusList.ptr)), nil ret := int(C.git_status_list_entrycount(statusList.ptr))
runtime.KeepAlive(statusList)
return ret, nil
} }
type StatusOpt int type StatusOpt int
@ -161,7 +169,7 @@ func (v *Repository) StatusList(opts *StatusOptions) (*StatusList, error) {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
return newStatusListFromC(ptr), nil return newStatusListFromC(ptr, v), nil
} }
func (v *Repository) StatusFile(path string) (Status, error) { func (v *Repository) StatusFile(path string) (Status, error) {
@ -173,6 +181,7 @@ func (v *Repository) StatusFile(path string) (Status, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_status_file(&statusFlags, v.ptr, cPath) ret := C.git_status_file(&statusFlags, v.ptr, cPath)
runtime.KeepAlive(v)
if ret < 0 { if ret < 0 {
return 0, MakeGitError(ret) return 0, MakeGitError(ret)
} }

View File

@ -21,6 +21,18 @@ type SubmoduleUpdateOptions struct {
// Submodule // Submodule
type Submodule struct { type Submodule struct {
ptr *C.git_submodule ptr *C.git_submodule
r *Repository
}
func newSubmoduleFromC(ptr *C.git_submodule, r *Repository) *Submodule {
s := &Submodule{ptr: ptr, r: r}
runtime.SetFinalizer(s, (*Submodule).Free)
return s
}
func (sub *Submodule) Free() {
runtime.SetFinalizer(sub, nil)
C.git_submodule_free(sub.ptr)
} }
type SubmoduleUpdate int type SubmoduleUpdate int
@ -82,24 +94,24 @@ func (c *SubmoduleCollection) Lookup(name string) (*Submodule, error) {
cname := C.CString(name) cname := C.CString(name)
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
sub := new(Submodule) var ptr *C.git_submodule
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_submodule_lookup(&sub.ptr, c.repo.ptr, cname) ret := C.git_submodule_lookup(&ptr, c.repo.ptr, cname)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
return sub, nil return newSubmoduleFromC(ptr, c.repo), nil
} }
type SubmoduleCbk func(sub *Submodule, name string) int type SubmoduleCbk func(sub *Submodule, name string) int
//export SubmoduleVisitor //export SubmoduleVisitor
func SubmoduleVisitor(csub unsafe.Pointer, name *C.char, handle unsafe.Pointer) C.int { func SubmoduleVisitor(csub unsafe.Pointer, name *C.char, handle unsafe.Pointer) C.int {
sub := &Submodule{(*C.git_submodule)(csub)} sub := &Submodule{(*C.git_submodule)(csub), nil}
if callback, ok := pointerHandles.Get(handle).(SubmoduleCbk); ok { if callback, ok := pointerHandles.Get(handle).(SubmoduleCbk); ok {
return (C.int)(callback(sub, C.GoString(name))) return (C.int)(callback(sub, C.GoString(name)))
@ -116,6 +128,7 @@ func (c *SubmoduleCollection) Foreach(cbk SubmoduleCbk) error {
defer pointerHandles.Untrack(handle) defer pointerHandles.Untrack(handle)
ret := C._go_git_visit_submodule(c.repo.ptr, handle) ret := C._go_git_visit_submodule(c.repo.ptr, handle)
runtime.KeepAlive(c)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -128,16 +141,15 @@ func (c *SubmoduleCollection) Add(url, path string, use_git_link bool) (*Submodu
cpath := C.CString(path) cpath := C.CString(path)
defer C.free(unsafe.Pointer(cpath)) defer C.free(unsafe.Pointer(cpath))
sub := new(Submodule)
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_submodule_add_setup(&sub.ptr, c.repo.ptr, curl, cpath, cbool(use_git_link)) var ptr *C.git_submodule
ret := C.git_submodule_add_setup(&ptr, c.repo.ptr, curl, cpath, cbool(use_git_link))
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
return sub, nil return newSubmoduleFromC(ptr, c.repo), nil
} }
func (sub *Submodule) FinalizeAdd() error { func (sub *Submodule) FinalizeAdd() error {
@ -145,6 +157,7 @@ func (sub *Submodule) FinalizeAdd() error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_submodule_add_finalize(sub.ptr) ret := C.git_submodule_add_finalize(sub.ptr)
runtime.KeepAlive(sub)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -156,6 +169,7 @@ func (sub *Submodule) AddToIndex(write_index bool) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_submodule_add_to_index(sub.ptr, cbool(write_index)) ret := C.git_submodule_add_to_index(sub.ptr, cbool(write_index))
runtime.KeepAlive(sub)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -163,18 +177,21 @@ func (sub *Submodule) AddToIndex(write_index bool) error {
} }
func (sub *Submodule) Name() string { func (sub *Submodule) Name() string {
n := C.git_submodule_name(sub.ptr) n := C.GoString(C.git_submodule_name(sub.ptr))
return C.GoString(n) runtime.KeepAlive(sub)
return n
} }
func (sub *Submodule) Path() string { func (sub *Submodule) Path() string {
n := C.git_submodule_path(sub.ptr) n := C.GoString(C.git_submodule_path(sub.ptr))
return C.GoString(n) runtime.KeepAlive(sub)
return n
} }
func (sub *Submodule) Url() string { func (sub *Submodule) Url() string {
n := C.git_submodule_url(sub.ptr) n := C.GoString(C.git_submodule_url(sub.ptr))
return C.GoString(n) runtime.KeepAlive(sub)
return n
} }
func (c *SubmoduleCollection) SetUrl(submodule, url string) error { func (c *SubmoduleCollection) SetUrl(submodule, url string) error {
@ -187,6 +204,7 @@ func (c *SubmoduleCollection) SetUrl(submodule, url string) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_submodule_set_url(c.repo.ptr, csubmodule, curl) ret := C.git_submodule_set_url(c.repo.ptr, csubmodule, curl)
runtime.KeepAlive(c)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -194,31 +212,38 @@ func (c *SubmoduleCollection) SetUrl(submodule, url string) error {
} }
func (sub *Submodule) IndexId() *Oid { func (sub *Submodule) IndexId() *Oid {
var id *Oid
idx := C.git_submodule_index_id(sub.ptr) idx := C.git_submodule_index_id(sub.ptr)
if idx == nil { if idx != nil {
return nil id = newOidFromC(idx)
} }
return newOidFromC(idx) runtime.KeepAlive(sub)
return id
} }
func (sub *Submodule) HeadId() *Oid { func (sub *Submodule) HeadId() *Oid {
var id *Oid
idx := C.git_submodule_head_id(sub.ptr) idx := C.git_submodule_head_id(sub.ptr)
if idx == nil { if idx != nil {
return nil id = newOidFromC(idx)
} }
return newOidFromC(idx) runtime.KeepAlive(sub)
return id
} }
func (sub *Submodule) WdId() *Oid { func (sub *Submodule) WdId() *Oid {
var id *Oid
idx := C.git_submodule_wd_id(sub.ptr) idx := C.git_submodule_wd_id(sub.ptr)
if idx == nil { if idx != nil {
return nil id = newOidFromC(idx)
} }
return newOidFromC(idx) runtime.KeepAlive(sub)
return id
} }
func (sub *Submodule) Ignore() SubmoduleIgnore { func (sub *Submodule) Ignore() SubmoduleIgnore {
o := C.git_submodule_ignore(sub.ptr) o := C.git_submodule_ignore(sub.ptr)
runtime.KeepAlive(sub)
return SubmoduleIgnore(o) return SubmoduleIgnore(o)
} }
@ -230,6 +255,7 @@ func (c *SubmoduleCollection) SetIgnore(submodule string, ignore SubmoduleIgnore
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_submodule_set_ignore(c.repo.ptr, csubmodule, C.git_submodule_ignore_t(ignore)) ret := C.git_submodule_set_ignore(c.repo.ptr, csubmodule, C.git_submodule_ignore_t(ignore))
runtime.KeepAlive(c)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -239,6 +265,7 @@ func (c *SubmoduleCollection) SetIgnore(submodule string, ignore SubmoduleIgnore
func (sub *Submodule) UpdateStrategy() SubmoduleUpdate { func (sub *Submodule) UpdateStrategy() SubmoduleUpdate {
o := C.git_submodule_update_strategy(sub.ptr) o := C.git_submodule_update_strategy(sub.ptr)
runtime.KeepAlive(sub)
return SubmoduleUpdate(o) return SubmoduleUpdate(o)
} }
@ -250,6 +277,7 @@ func (c *SubmoduleCollection) SetUpdate(submodule string, update SubmoduleUpdate
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_submodule_set_update(c.repo.ptr, csubmodule, C.git_submodule_update_t(update)) ret := C.git_submodule_set_update(c.repo.ptr, csubmodule, C.git_submodule_update_t(update))
runtime.KeepAlive(c)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -269,6 +297,7 @@ func (c *SubmoduleCollection) SetFetchRecurseSubmodules(submodule string, recurs
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_submodule_set_fetch_recurse_submodules(c.repo.ptr, csubmodule, C.git_submodule_recurse_t(recurse)) ret := C.git_submodule_set_fetch_recurse_submodules(c.repo.ptr, csubmodule, C.git_submodule_recurse_t(recurse))
runtime.KeepAlive(c)
if ret < 0 { if ret < 0 {
return MakeGitError(C.int(ret)) return MakeGitError(C.int(ret))
} }
@ -280,6 +309,7 @@ func (sub *Submodule) Init(overwrite bool) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_submodule_init(sub.ptr, cbool(overwrite)) ret := C.git_submodule_init(sub.ptr, cbool(overwrite))
runtime.KeepAlive(sub)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -291,6 +321,7 @@ func (sub *Submodule) Sync() error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_submodule_sync(sub.ptr) ret := C.git_submodule_sync(sub.ptr)
runtime.KeepAlive(sub)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -303,6 +334,7 @@ func (sub *Submodule) Open() (*Repository, error) {
var ptr *C.git_repository var ptr *C.git_repository
ret := C.git_submodule_open(&ptr, sub.ptr) ret := C.git_submodule_open(&ptr, sub.ptr)
runtime.KeepAlive(sub)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -320,6 +352,7 @@ func (sub *Submodule) Update(init bool, opts *SubmoduleUpdateOptions) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_submodule_update(sub.ptr, cbool(init), &copts) ret := C.git_submodule_update(sub.ptr, cbool(init), &copts)
runtime.KeepAlive(sub)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }

28
tag.go
View File

@ -18,22 +18,28 @@ type Tag struct {
} }
func (t Tag) Message() string { func (t Tag) Message() string {
return C.GoString(C.git_tag_message(t.cast_ptr)) ret := C.GoString(C.git_tag_message(t.cast_ptr))
runtime.KeepAlive(t)
return ret
} }
func (t Tag) Name() string { func (t Tag) Name() string {
return C.GoString(C.git_tag_name(t.cast_ptr)) ret := C.GoString(C.git_tag_name(t.cast_ptr))
runtime.KeepAlive(t)
return ret
} }
func (t Tag) Tagger() *Signature { func (t Tag) Tagger() *Signature {
cast_ptr := C.git_tag_tagger(t.cast_ptr) cast_ptr := C.git_tag_tagger(t.cast_ptr)
return newSignatureFromC(cast_ptr) ret := newSignatureFromC(cast_ptr)
runtime.KeepAlive(t)
return ret
} }
func (t Tag) Target() *Object { func (t Tag) Target() *Object {
var ptr *C.git_object var ptr *C.git_object
ret := C.git_tag_target(&ptr, t.cast_ptr) ret := C.git_tag_target(&ptr, t.cast_ptr)
runtime.KeepAlive(t)
if ret != 0 { if ret != 0 {
return nil return nil
} }
@ -42,11 +48,15 @@ func (t Tag) Target() *Object {
} }
func (t Tag) TargetId() *Oid { func (t Tag) TargetId() *Oid {
return newOidFromC(C.git_tag_target_id(t.cast_ptr)) ret := newOidFromC(C.git_tag_target_id(t.cast_ptr))
runtime.KeepAlive(t)
return ret
} }
func (t Tag) TargetType() ObjectType { func (t Tag) TargetType() ObjectType {
return ObjectType(C.git_tag_target_type(t.cast_ptr)) ret := ObjectType(C.git_tag_target_type(t.cast_ptr))
runtime.KeepAlive(t)
return ret
} }
type TagsCollection struct { type TagsCollection struct {
@ -76,6 +86,7 @@ func (c *TagsCollection) Create(
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_tag_create(oid.toC(), c.repo.ptr, cname, ctarget, taggerSig, cmessage, 0) ret := C.git_tag_create(oid.toC(), c.repo.ptr, cname, ctarget, taggerSig, cmessage, 0)
runtime.KeepAlive(c)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -91,6 +102,7 @@ func (c *TagsCollection) Remove(name string) error {
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
ret := C.git_tag_delete(c.repo.ptr, cname) ret := C.git_tag_delete(c.repo.ptr, cname)
runtime.KeepAlive(c)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
@ -123,6 +135,7 @@ func (c *TagsCollection) CreateLightweight(name string, commit *Commit, force bo
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
err := C.git_tag_create_lightweight(oid.toC(), c.repo.ptr, cname, ctarget, cbool(force)) err := C.git_tag_create_lightweight(oid.toC(), c.repo.ptr, cname, ctarget, cbool(force))
runtime.KeepAlive(c)
if err < 0 { if err < 0 {
return nil, MakeGitError(err) return nil, MakeGitError(err)
} }
@ -139,6 +152,7 @@ func (c *TagsCollection) List() ([]string, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ecode := C.git_tag_list(&strC, c.repo.ptr) ecode := C.git_tag_list(&strC, c.repo.ptr)
runtime.KeepAlive(c)
if ecode < 0 { if ecode < 0 {
return nil, MakeGitError(ecode) return nil, MakeGitError(ecode)
} }
@ -162,6 +176,7 @@ func (c *TagsCollection) ListWithMatch(pattern string) ([]string, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ecode := C.git_tag_list_match(&strC, patternC, c.repo.ptr) ecode := C.git_tag_list_match(&strC, patternC, c.repo.ptr)
runtime.KeepAlive(c)
if ecode < 0 { if ecode < 0 {
return nil, MakeGitError(ecode) return nil, MakeGitError(ecode)
} }
@ -215,6 +230,7 @@ func (c *TagsCollection) Foreach(callback TagForeachCallback) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
err := C._go_git_tag_foreach(c.repo.ptr, handle) err := C._go_git_tag_foreach(c.repo.ptr, handle)
runtime.KeepAlive(c)
if err == C.GIT_EUSER { if err == C.GIT_EUSER {
return data.err return data.err
} }

13
tree.go
View File

@ -48,6 +48,7 @@ func (t Tree) EntryByName(filename string) *TreeEntry {
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
entry := C.git_tree_entry_byname(t.cast_ptr, cname) entry := C.git_tree_entry_byname(t.cast_ptr, cname)
runtime.KeepAlive(t)
if entry == nil { if entry == nil {
return nil return nil
} }
@ -66,6 +67,8 @@ func (t Tree) EntryById(id *Oid) *TreeEntry {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
entry := C.git_tree_entry_byid(t.cast_ptr, id.toC()) entry := C.git_tree_entry_byid(t.cast_ptr, id.toC())
runtime.KeepAlive(t)
runtime.KeepAlive(id)
if entry == nil { if entry == nil {
return nil return nil
} }
@ -84,6 +87,7 @@ func (t Tree) EntryByPath(path string) (*TreeEntry, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_tree_entry_bypath(&entry, t.cast_ptr, cpath) ret := C.git_tree_entry_bypath(&entry, t.cast_ptr, cpath)
runtime.KeepAlive(t)
if ret < 0 { if ret < 0 {
return nil, MakeGitError(ret) return nil, MakeGitError(ret)
} }
@ -94,6 +98,7 @@ func (t Tree) EntryByPath(path string) (*TreeEntry, error) {
func (t Tree) EntryByIndex(index uint64) *TreeEntry { func (t Tree) EntryByIndex(index uint64) *TreeEntry {
entry := C.git_tree_entry_byindex(t.cast_ptr, C.size_t(index)) entry := C.git_tree_entry_byindex(t.cast_ptr, C.size_t(index))
runtime.KeepAlive(t)
if entry == nil { if entry == nil {
return nil return nil
} }
@ -103,6 +108,7 @@ func (t Tree) EntryByIndex(index uint64) *TreeEntry {
func (t Tree) EntryCount() uint64 { func (t Tree) EntryCount() uint64 {
num := C.git_tree_entrycount(t.cast_ptr) num := C.git_tree_entrycount(t.cast_ptr)
runtime.KeepAlive(t)
return uint64(num) return uint64(num)
} }
@ -132,7 +138,7 @@ func (t Tree) Walk(callback TreeWalkCallback) error {
C.GIT_TREEWALK_PRE, C.GIT_TREEWALK_PRE,
ptr, ptr,
) )
runtime.KeepAlive(t)
if err < 0 { if err < 0 {
return MakeGitError(err) return MakeGitError(err)
} }
@ -158,6 +164,8 @@ func (v *TreeBuilder) Insert(filename string, id *Oid, filemode Filemode) error
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
err := C.git_treebuilder_insert(nil, v.ptr, cfilename, id.toC(), C.git_filemode_t(filemode)) err := C.git_treebuilder_insert(nil, v.ptr, cfilename, id.toC(), C.git_filemode_t(filemode))
runtime.KeepAlive(v)
runtime.KeepAlive(id)
if err < 0 { if err < 0 {
return MakeGitError(err) return MakeGitError(err)
} }
@ -173,6 +181,7 @@ func (v *TreeBuilder) Remove(filename string) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
err := C.git_treebuilder_remove(v.ptr, cfilename) err := C.git_treebuilder_remove(v.ptr, cfilename)
runtime.KeepAlive(v)
if err < 0 { if err < 0 {
return MakeGitError(err) return MakeGitError(err)
} }
@ -187,7 +196,7 @@ func (v *TreeBuilder) Write() (*Oid, error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
err := C.git_treebuilder_write(oid.toC(), v.ptr) err := C.git_treebuilder_write(oid.toC(), v.ptr)
runtime.KeepAlive(v)
if err < 0 { if err < 0 {
return nil, MakeGitError(err) return nil, MakeGitError(err)
} }

16
walk.go
View File

@ -34,6 +34,7 @@ func revWalkFromC(repo *Repository, c *C.git_revwalk) *RevWalk {
func (v *RevWalk) Reset() { func (v *RevWalk) Reset() {
C.git_revwalk_reset(v.ptr) C.git_revwalk_reset(v.ptr)
runtime.KeepAlive(v)
} }
func (v *RevWalk) Push(id *Oid) error { func (v *RevWalk) Push(id *Oid) error {
@ -41,6 +42,8 @@ func (v *RevWalk) Push(id *Oid) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ecode := C.git_revwalk_push(v.ptr, id.toC()) ecode := C.git_revwalk_push(v.ptr, id.toC())
runtime.KeepAlive(v)
runtime.KeepAlive(id)
if ecode < 0 { if ecode < 0 {
return MakeGitError(ecode) return MakeGitError(ecode)
} }
@ -55,6 +58,7 @@ func (v *RevWalk) PushGlob(glob string) error {
defer C.free(unsafe.Pointer(cstr)) defer C.free(unsafe.Pointer(cstr))
ecode := C.git_revwalk_push_glob(v.ptr, cstr) ecode := C.git_revwalk_push_glob(v.ptr, cstr)
runtime.KeepAlive(v)
if ecode < 0 { if ecode < 0 {
return MakeGitError(ecode) return MakeGitError(ecode)
} }
@ -69,6 +73,7 @@ func (v *RevWalk) PushRange(r string) error {
defer C.free(unsafe.Pointer(cstr)) defer C.free(unsafe.Pointer(cstr))
ecode := C.git_revwalk_push_range(v.ptr, cstr) ecode := C.git_revwalk_push_range(v.ptr, cstr)
runtime.KeepAlive(v)
if ecode < 0 { if ecode < 0 {
return MakeGitError(ecode) return MakeGitError(ecode)
} }
@ -83,6 +88,7 @@ func (v *RevWalk) PushRef(r string) error {
defer C.free(unsafe.Pointer(cstr)) defer C.free(unsafe.Pointer(cstr))
ecode := C.git_revwalk_push_ref(v.ptr, cstr) ecode := C.git_revwalk_push_ref(v.ptr, cstr)
runtime.KeepAlive(v)
if ecode < 0 { if ecode < 0 {
return MakeGitError(ecode) return MakeGitError(ecode)
} }
@ -94,6 +100,7 @@ func (v *RevWalk) PushHead() (err error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ecode := C.git_revwalk_push_head(v.ptr) ecode := C.git_revwalk_push_head(v.ptr)
runtime.KeepAlive(v)
if ecode < 0 { if ecode < 0 {
err = MakeGitError(ecode) err = MakeGitError(ecode)
} }
@ -105,6 +112,8 @@ func (v *RevWalk) Hide(id *Oid) error {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ecode := C.git_revwalk_hide(v.ptr, id.toC()) ecode := C.git_revwalk_hide(v.ptr, id.toC())
runtime.KeepAlive(v)
runtime.KeepAlive(id)
if ecode < 0 { if ecode < 0 {
return MakeGitError(ecode) return MakeGitError(ecode)
} }
@ -119,6 +128,7 @@ func (v *RevWalk) HideGlob(glob string) error {
defer C.free(unsafe.Pointer(cstr)) defer C.free(unsafe.Pointer(cstr))
ecode := C.git_revwalk_hide_glob(v.ptr, cstr) ecode := C.git_revwalk_hide_glob(v.ptr, cstr)
runtime.KeepAlive(v)
if ecode < 0 { if ecode < 0 {
return MakeGitError(ecode) return MakeGitError(ecode)
} }
@ -133,6 +143,7 @@ func (v *RevWalk) HideRef(r string) error {
defer C.free(unsafe.Pointer(cstr)) defer C.free(unsafe.Pointer(cstr))
ecode := C.git_revwalk_hide_ref(v.ptr, cstr) ecode := C.git_revwalk_hide_ref(v.ptr, cstr)
runtime.KeepAlive(v)
if ecode < 0 { if ecode < 0 {
return MakeGitError(ecode) return MakeGitError(ecode)
} }
@ -144,6 +155,7 @@ func (v *RevWalk) HideHead() (err error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ecode := C.git_revwalk_hide_head(v.ptr) ecode := C.git_revwalk_hide_head(v.ptr)
runtime.KeepAlive(v)
if ecode < 0 { if ecode < 0 {
err = MakeGitError(ecode) err = MakeGitError(ecode)
} }
@ -155,6 +167,7 @@ func (v *RevWalk) Next(id *Oid) (err error) {
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_revwalk_next(id.toC(), v.ptr) ret := C.git_revwalk_next(id.toC(), v.ptr)
runtime.KeepAlive(v)
switch { switch {
case ret < 0: case ret < 0:
err = MakeGitError(ret) err = MakeGitError(ret)
@ -192,14 +205,15 @@ func (v *RevWalk) Iterate(fun RevWalkIterator) (err error) {
func (v *RevWalk) SimplifyFirstParent() { func (v *RevWalk) SimplifyFirstParent() {
C.git_revwalk_simplify_first_parent(v.ptr) C.git_revwalk_simplify_first_parent(v.ptr)
runtime.KeepAlive(v)
} }
func (v *RevWalk) Sorting(sm SortType) { func (v *RevWalk) Sorting(sm SortType) {
C.git_revwalk_sorting(v.ptr, C.uint(sm)) C.git_revwalk_sorting(v.ptr, C.uint(sm))
runtime.KeepAlive(v)
} }
func (v *RevWalk) Free() { func (v *RevWalk) Free() {
runtime.SetFinalizer(v, nil) runtime.SetFinalizer(v, nil)
C.git_revwalk_free(v.ptr) C.git_revwalk_free(v.ptr)
} }