Making things work with libgit2 at 2dc49ea #54

Closed
meatballhat wants to merge 8 commits from working-with-libgit2-at-2dc49ea into master
17 changed files with 261 additions and 49 deletions

View File

@ -22,4 +22,3 @@ func (v Blob) Contents() []byte {
buffer := unsafe.Pointer(C.git_blob_rawcontent(v.ptr)) buffer := unsafe.Pointer(C.git_blob_rawcontent(v.ptr))
return C.GoBytes(buffer, size) return C.GoBytes(buffer, size)
} }

View File

@ -10,6 +10,7 @@ git_checkout_opts git_checkout_opts_init() {
import "C" import "C"
import ( import (
"os" "os"
"runtime"
) )
type CheckoutStrategy uint type CheckoutStrategy uint
@ -59,6 +60,9 @@ func (v *Repository) Checkout(opts *CheckoutOpts) error {
var copts C.git_checkout_opts var copts C.git_checkout_opts
populateCheckoutOpts(&copts, opts) populateCheckoutOpts(&copts, opts)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_checkout_head(v.ptr, &copts) ret := C.git_checkout_head(v.ptr, &copts)
if ret < 0 { if ret < 0 {
return LastError() return LastError()
@ -72,6 +76,9 @@ func (v *Repository) CheckoutIndex(index *Index, opts *CheckoutOpts) error {
var copts C.git_checkout_opts var copts C.git_checkout_opts
populateCheckoutOpts(&copts, opts) populateCheckoutOpts(&copts, opts)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_checkout_index(v.ptr, index.ptr, &copts) ret := C.git_checkout_index(v.ptr, index.ptr, &copts)
if ret < 0 { if ret < 0 {
return LastError() return LastError()

View File

@ -9,8 +9,9 @@ extern int _go_git_treewalk(git_tree *tree, git_treewalk_mode mode, void *ptr);
import "C" import "C"
import ( import (
"unsafe" "runtime"
"time" "time"
"unsafe"
) )
// Commit // Commit
@ -25,6 +26,9 @@ func (c Commit) Message() string {
func (c Commit) Tree() (*Tree, error) { func (c Commit) Tree() (*Tree, error) {
var ptr *C.git_object var ptr *C.git_object
runtime.LockOSThread()
defer runtime.UnlockOSThread()
err := C.git_commit_tree(&ptr, c.ptr) err := C.git_commit_tree(&ptr, c.ptr)
if err < 0 { if err < 0 {
return nil, LastError() return nil, LastError()
@ -48,12 +52,13 @@ func (c Commit) Committer() *Signature {
} }
func (c *Commit) Parent(n uint) *Commit { func (c *Commit) Parent(n uint) *Commit {
par := &Commit{} var cobj *C.git_object
ret := C.git_commit_parent(&par.ptr, c.ptr, C.uint(n)) ret := C.git_commit_parent(&cobj, c.ptr, C.uint(n))
if ret != 0 { if ret != 0 {
return nil return nil
} }
return par
return allocObject(cobj).(*Commit)
} }
func (c *Commit) ParentId(n uint) *Oid { func (c *Commit) ParentId(n uint) *Oid {
@ -85,10 +90,10 @@ func newSignatureFromC(sig *C.git_signature) *Signature {
// the offset in mintes, which is what git wants // the offset in mintes, which is what git wants
func (v *Signature) Offset() int { func (v *Signature) Offset() int {
_, offset := v.When.Zone() _, offset := v.When.Zone()
return offset/60 return offset / 60
} }
func (sig *Signature) toC() (*C.git_signature) { func (sig *Signature) toC() *C.git_signature {
var out *C.git_signature var out *C.git_signature
name := C.CString(sig.Name) name := C.CString(sig.Name)

View File

@ -6,6 +6,7 @@ package git
*/ */
import "C" import "C"
import ( import (
"runtime"
"unsafe" "unsafe"
) )
@ -18,6 +19,9 @@ func (c *Config) LookupInt32(name string) (v int32, err error) {
cname := C.CString(name) cname := C.CString(name)
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_config_get_int32(&out, c.ptr, cname) ret := C.git_config_get_int32(&out, c.ptr, cname)
if ret < 0 { if ret < 0 {
return 0, LastError() return 0, LastError()
@ -31,6 +35,9 @@ func (c *Config) LookupInt64(name string) (v int64, err error) {
cname := C.CString(name) cname := C.CString(name)
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_config_get_int64(&out, c.ptr, cname) ret := C.git_config_get_int64(&out, c.ptr, cname)
if ret < 0 { if ret < 0 {
return 0, LastError() return 0, LastError()
@ -44,6 +51,9 @@ func (c *Config) LookupString(name string) (v string, err error) {
cname := C.CString(name) cname := C.CString(name)
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_config_get_string(&ptr, c.ptr, cname) ret := C.git_config_get_string(&ptr, c.ptr, cname)
if ret < 0 { if ret < 0 {
return "", LastError() return "", LastError()
@ -59,6 +69,9 @@ func (c *Config) Set(name, value string) (err error) {
cvalue := C.CString(value) cvalue := C.CString(value)
defer C.free(unsafe.Pointer(cvalue)) defer C.free(unsafe.Pointer(cvalue))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_config_set_string(c.ptr, cname, cvalue) ret := C.git_config_set_string(c.ptr, cname, cvalue)
if ret < 0 { if ret < 0 {
return LastError() return LastError()
@ -66,3 +79,8 @@ func (c *Config) Set(name, value string) (err error) {
return nil return nil
} }
func (c *Config) Free() {
runtime.SetFinalizer(c, nil)
C.git_config_free(c.ptr)
}

11
git.go
View File

@ -9,6 +9,7 @@ import "C"
import ( import (
"bytes" "bytes"
"errors" "errors"
"runtime"
"strings" "strings"
"unsafe" "unsafe"
) )
@ -57,6 +58,9 @@ func NewOidFromString(s string) (*Oid, error) {
cs := C.CString(s) cs := C.CString(s)
defer C.free(unsafe.Pointer(cs)) defer C.free(unsafe.Pointer(cs))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if C.git_oid_fromstr(o.toC(), cs) < 0 { if C.git_oid_fromstr(o.toC(), cs) < 0 {
return nil, LastError() return nil, LastError()
} }
@ -109,6 +113,10 @@ func ShortenOids(ids []*Oid, minlen int) (int, error) {
defer C.git_oid_shorten_free(shorten) defer C.git_oid_shorten_free(shorten)
var ret C.int var ret C.int
runtime.LockOSThread()
defer runtime.UnlockOSThread()
for _, id := range ids { for _, id := range ids {
buf := make([]byte, 41) buf := make([]byte, 41)
C.git_oid_fmt((*C.char)(unsafe.Pointer(&buf[0])), id.toC()) C.git_oid_fmt((*C.char)(unsafe.Pointer(&buf[0])), id.toC())
@ -162,6 +170,9 @@ func Discover(start string, across_fs bool, ceiling_dirs []string) (string, erro
retpath := (*C.git_buf)(C.malloc(C.GIT_PATH_MAX)) retpath := (*C.git_buf)(C.malloc(C.GIT_PATH_MAX))
defer C.git_buf_free(retpath) defer C.git_buf_free(retpath)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
r := C.git_repository_discover(retpath, cstart, cbool(across_fs), ceildirs) r := C.git_repository_discover(retpath, cstart, cbool(across_fs), ceildirs)
if r == 0 { if r == 0 {

View File

@ -1,8 +1,8 @@
package git package git
import ( import (
"testing"
"io/ioutil" "io/ioutil"
"testing"
"time" "time"
) )
@ -14,7 +14,7 @@ func createTestRepo(t *testing.T) *Repository {
checkFatal(t, err) checkFatal(t, err)
tmpfile := "README" tmpfile := "README"
err = ioutil.WriteFile(path + "/" + tmpfile, []byte("foo\n"), 0644) err = ioutil.WriteFile(path+"/"+tmpfile, []byte("foo\n"), 0644)
checkFatal(t, err) checkFatal(t, err)
return repo return repo
@ -44,4 +44,3 @@ func seedTestRepo(t *testing.T, repo *Repository) (*Oid, *Oid) {
return commitId, treeId return commitId, treeId
} }

View File

@ -24,6 +24,9 @@ func (v *Index) AddByPath(path string) error {
cstr := C.CString(path) cstr := C.CString(path)
defer C.free(unsafe.Pointer(cstr)) defer C.free(unsafe.Pointer(cstr))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_index_add_bypath(v.ptr, cstr) ret := C.git_index_add_bypath(v.ptr, cstr)
if ret < 0 { if ret < 0 {
return LastError() return LastError()
@ -34,6 +37,10 @@ func (v *Index) AddByPath(path string) error {
func (v *Index) WriteTree() (*Oid, error) { func (v *Index) WriteTree() (*Oid, error) {
oid := new(Oid) oid := new(Oid)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_index_write_tree(oid.toC(), v.ptr) ret := C.git_index_write_tree(oid.toC(), v.ptr)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()

View File

@ -28,8 +28,8 @@ type gitObject struct {
ptr *C.git_object ptr *C.git_object
} }
func (t ObjectType) String() (string) { func (t ObjectType) String() string {
switch (t) { switch t {
case ObjectAny: case ObjectAny:
return "Any" return "Any"
case ObjectBad: case ObjectBad:

12
odb.go
View File

@ -8,9 +8,9 @@ extern int _go_git_odb_foreach(git_odb *db, void *payload);
*/ */
import "C" import "C"
import ( import (
"unsafe"
"reflect" "reflect"
"runtime" "runtime"
"unsafe"
) )
type Odb struct { type Odb struct {
@ -25,6 +25,10 @@ func (v *Odb) Exists(oid *Oid) bool {
func (v *Odb) Write(data []byte, otype ObjectType) (oid *Oid, err error) { func (v *Odb) Write(data []byte, otype ObjectType) (oid *Oid, err error) {
oid = new(Oid) oid = new(Oid)
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&data)) hdr := (*reflect.SliceHeader)(unsafe.Pointer(&data))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_odb_write(oid.toC(), v.ptr, unsafe.Pointer(hdr.Data), C.size_t(hdr.Len), C.git_otype(otype)) ret := C.git_odb_write(oid.toC(), v.ptr, unsafe.Pointer(hdr.Data), C.size_t(hdr.Len), C.git_otype(otype))
if ret < 0 { if ret < 0 {
@ -36,6 +40,10 @@ func (v *Odb) Write(data []byte, otype ObjectType) (oid *Oid, err error) {
func (v *Odb) Read(oid *Oid) (obj *OdbObject, err error) { func (v *Odb) Read(oid *Oid) (obj *OdbObject, err error) {
obj = new(OdbObject) obj = new(OdbObject)
runtime.LockOSThread()
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())
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -57,7 +65,7 @@ func odbForEachCb(id *C.git_oid, payload unsafe.Pointer) int {
case <-ch: case <-ch:
return -1 return -1
} }
return 0; return 0
} }
func (v *Odb) forEachWrap(ch chan *Oid) { func (v *Odb) forEachWrap(ch chan *Oid) {

View File

@ -22,6 +22,10 @@ type Packbuilder struct {
func (repo *Repository) NewPackbuilder() (*Packbuilder, error) { func (repo *Repository) NewPackbuilder() (*Packbuilder, error) {
builder := &Packbuilder{} builder := &Packbuilder{}
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_packbuilder_new(&builder.ptr, repo.ptr) ret := C.git_packbuilder_new(&builder.ptr, repo.ptr)
if ret != 0 { if ret != 0 {
return nil, LastError() return nil, LastError()
@ -38,6 +42,10 @@ func (pb *Packbuilder) Free() {
func (pb *Packbuilder) Insert(id *Oid, name string) error { func (pb *Packbuilder) Insert(id *Oid, name string) error {
cname := C.CString(name) cname := C.CString(name)
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_packbuilder_insert(pb.ptr, id.toC(), cname) ret := C.git_packbuilder_insert(pb.ptr, id.toC(), cname)
if ret != 0 { if ret != 0 {
return LastError() return LastError()
@ -46,6 +54,9 @@ func (pb *Packbuilder) Insert(id *Oid, name string) error {
} }
func (pb *Packbuilder) InsertCommit(id *Oid) error { func (pb *Packbuilder) InsertCommit(id *Oid) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_packbuilder_insert_commit(pb.ptr, id.toC()) ret := C.git_packbuilder_insert_commit(pb.ptr, id.toC())
if ret != 0 { if ret != 0 {
return LastError() return LastError()
@ -54,6 +65,9 @@ func (pb *Packbuilder) InsertCommit(id *Oid) error {
} }
func (pb *Packbuilder) InsertTree(id *Oid) error { func (pb *Packbuilder) InsertTree(id *Oid) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_packbuilder_insert_tree(pb.ptr, id.toC()) ret := C.git_packbuilder_insert_tree(pb.ptr, id.toC())
if ret != 0 { if ret != 0 {
return LastError() return LastError()
@ -68,6 +82,10 @@ func (pb *Packbuilder) ObjectCount() uint32 {
func (pb *Packbuilder) WriteToFile(name string, mode os.FileMode) error { func (pb *Packbuilder) WriteToFile(name string, mode os.FileMode) error {
cname := C.CString(name) cname := C.CString(name)
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
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)
if ret != 0 { if ret != 0 {
return LastError() return LastError()
@ -104,7 +122,7 @@ func packbuilderForEachCb(buf unsafe.Pointer, size C.size_t, payload unsafe.Poin
slice := C.GoBytes(buf, C.int(size)) slice := C.GoBytes(buf, C.int(size))
select { select {
case <- stop: case <-stop:
return -1 return -1
case ch <- slice: case ch <- slice:
} }

View File

@ -40,6 +40,9 @@ func (v *Reference) SetSymbolicTarget(target string, sig *Signature, msg string)
cmsg := C.CString(msg) cmsg := C.CString(msg)
defer C.free(unsafe.Pointer(cmsg)) defer C.free(unsafe.Pointer(cmsg))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_reference_symbolic_set_target(&ptr, v.ptr, ctarget, csig, cmsg) ret := C.git_reference_symbolic_set_target(&ptr, v.ptr, ctarget, csig, cmsg)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -68,6 +71,9 @@ func (v *Reference) SetTarget(target *Oid, sig *Signature, msg string) (*Referen
func (v *Reference) Resolve() (*Reference, error) { func (v *Reference) Resolve() (*Reference, error) {
var ptr *C.git_reference var ptr *C.git_reference
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_reference_resolve(&ptr, v.ptr) ret := C.git_reference_resolve(&ptr, v.ptr)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -76,12 +82,18 @@ func (v *Reference) Resolve() (*Reference, error) {
return newReferenceFromC(ptr), nil return newReferenceFromC(ptr), nil
} }
func (v *Reference) Rename(name string, force bool) (*Reference, error) { func (v *Reference) Rename(name string, force bool, logMsg string) (*Reference, error) {
var ptr *C.git_reference var ptr *C.git_reference
cname := C.CString(name) cname := C.CString(name)
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
ret := C.git_reference_rename(&ptr, v.ptr, cname, cbool(force)) cLogMsg := C.CString(logMsg)
defer C.free(unsafe.Pointer(cLogMsg))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_reference_rename(&ptr, v.ptr, cname, cbool(force), nil, cLogMsg)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -104,6 +116,9 @@ func (v *Reference) SymbolicTarget() string {
} }
func (v *Reference) Delete() error { func (v *Reference) Delete() error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_reference_delete(v.ptr) ret := C.git_reference_delete(v.ptr)
if ret < 0 { if ret < 0 {
@ -134,6 +149,10 @@ type ReferenceIterator struct {
// NewReferenceIterator creates a new iterator over reference names // NewReferenceIterator creates a new iterator over reference names
func (repo *Repository) NewReferenceIterator() (*ReferenceIterator, error) { func (repo *Repository) NewReferenceIterator() (*ReferenceIterator, error) {
var ptr *C.git_reference_iterator var ptr *C.git_reference_iterator
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_reference_iterator_new(&ptr, repo.ptr) ret := C.git_reference_iterator_new(&ptr, repo.ptr)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -151,6 +170,10 @@ func (repo *Repository) NewReferenceIteratorGlob(glob string) (*ReferenceIterato
cstr := C.CString(glob) cstr := C.CString(glob)
defer C.free(unsafe.Pointer(cstr)) defer C.free(unsafe.Pointer(cstr))
var ptr *C.git_reference_iterator var ptr *C.git_reference_iterator
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_reference_iterator_glob_new(&ptr, repo.ptr, cstr) ret := C.git_reference_iterator_glob_new(&ptr, repo.ptr, cstr)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -165,6 +188,10 @@ func (repo *Repository) NewReferenceIteratorGlob(glob string) (*ReferenceIterato
// the returned error is git.ErrIterOver // the returned error is git.ErrIterOver
func (v *ReferenceIterator) NextName() (string, error) { func (v *ReferenceIterator) NextName() (string, error) {
var ptr *C.char var ptr *C.char
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_reference_next_name(&ptr, v.ptr) ret := C.git_reference_next_name(&ptr, v.ptr)
if ret == ITEROVER { if ret == ITEROVER {
return "", ErrIterOver return "", ErrIterOver

View File

@ -52,7 +52,7 @@ func TestRefModification(t *testing.T) {
t.Fatalf("Wrong ref target") t.Fatalf("Wrong ref target")
} }
_, err = tag.Rename("refs/tags/renamed", false) _, err = tag.Rename("refs/tags/renamed", false, "")
checkFatal(t, err) checkFatal(t, err)
tag, err = repo.LookupReference("refs/tags/renamed") tag, err = repo.LookupReference("refs/tags/renamed")
checkFatal(t, err) checkFatal(t, err)

View File

@ -21,6 +21,9 @@ func OpenRepository(path string) (*Repository, error) {
cpath := C.CString(path) cpath := C.CString(path)
defer C.free(unsafe.Pointer(cpath)) defer C.free(unsafe.Pointer(cpath))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_repository_open(&repo.ptr, cpath) ret := C.git_repository_open(&repo.ptr, cpath)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -36,6 +39,9 @@ func InitRepository(path string, isbare bool) (*Repository, error) {
cpath := C.CString(path) cpath := C.CString(path)
defer C.free(unsafe.Pointer(cpath)) defer C.free(unsafe.Pointer(cpath))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_repository_init(&repo.ptr, cpath, ucbool(isbare)) ret := C.git_repository_init(&repo.ptr, cpath, ucbool(isbare))
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -53,16 +59,24 @@ func (v *Repository) Free() {
func (v *Repository) Config() (*Config, error) { func (v *Repository) Config() (*Config, error) {
config := new(Config) config := new(Config)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_repository_config(&config.ptr, v.ptr) ret := C.git_repository_config(&config.ptr, v.ptr)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
} }
runtime.SetFinalizer(config, (*Config).Free)
return config, nil return config, nil
} }
func (v *Repository) Index() (*Index, error) { func (v *Repository) Index() (*Index, error) {
var ptr *C.git_index var ptr *C.git_index
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_repository_index(&ptr, v.ptr) ret := C.git_repository_index(&ptr, v.ptr)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -73,6 +87,10 @@ func (v *Repository) Index() (*Index, error) {
func (v *Repository) lookupType(oid *Oid, t ObjectType) (Object, error) { func (v *Repository) lookupType(oid *Oid, t ObjectType) (Object, error) {
var ptr *C.git_object var ptr *C.git_object
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_object_lookup(&ptr, v.ptr, oid.toC(), C.git_otype(t)) ret := C.git_object_lookup(&ptr, v.ptr, oid.toC(), C.git_otype(t))
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -117,6 +135,9 @@ func (v *Repository) LookupReference(name string) (*Reference, error) {
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
var ptr *C.git_reference var ptr *C.git_reference
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_reference_lookup(&ptr, v.ptr, cname) ecode := C.git_reference_lookup(&ptr, v.ptr, cname)
if ecode < 0 { if ecode < 0 {
return nil, LastError() return nil, LastError()
@ -137,6 +158,9 @@ func (v *Repository) CreateReference(name string, oid *Oid, force bool, sig *Sig
var ptr *C.git_reference var ptr *C.git_reference
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_reference_create(&ptr, v.ptr, cname, oid.toC(), cbool(force), csig, cmsg) ecode := C.git_reference_create(&ptr, v.ptr, cname, oid.toC(), cbool(force), csig, cmsg)
if ecode < 0 { if ecode < 0 {
return nil, LastError() return nil, LastError()
@ -158,6 +182,9 @@ func (v *Repository) CreateSymbolicReference(name, target string, force bool, si
cmsg := C.CString(msg) cmsg := C.CString(msg)
defer C.free(unsafe.Pointer(cmsg)) defer C.free(unsafe.Pointer(cmsg))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
var ptr *C.git_reference var ptr *C.git_reference
ecode := C.git_reference_symbolic_create(&ptr, v.ptr, cname, ctarget, cbool(force), csig, cmsg) ecode := C.git_reference_symbolic_create(&ptr, v.ptr, cname, ctarget, cbool(force), csig, cmsg)
@ -170,6 +197,10 @@ func (v *Repository) CreateSymbolicReference(name, target string, force bool, si
func (v *Repository) Walk() (*RevWalk, error) { func (v *Repository) Walk() (*RevWalk, error) {
walk := new(RevWalk) walk := new(RevWalk)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_revwalk_new(&walk.ptr, v.ptr) ecode := C.git_revwalk_new(&walk.ptr, v.ptr)
if ecode < 0 { if ecode < 0 {
return nil, LastError() return nil, LastError()
@ -210,10 +241,13 @@ func (v *Repository) CreateCommit(
committerSig := committer.toC() committerSig := committer.toC()
defer C.git_signature_free(committerSig) defer C.git_signature_free(committerSig)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_commit_create( ret := C.git_commit_create(
oid.toC(), v.ptr, cref, oid.toC(), v.ptr, cref,
authorSig, committerSig, authorSig, committerSig,
nil, cmsg, tree.ptr, C.int(nparents), parentsarg) nil, cmsg, tree.ptr, C.size_t(nparents), parentsarg)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -229,6 +263,10 @@ func (v *Odb) Free() {
func (v *Repository) Odb() (odb *Odb, err error) { func (v *Repository) Odb() (odb *Odb, err error) {
odb = new(Odb) odb = new(Odb)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if ret := C.git_repository_odb(&odb.ptr, v.ptr); ret < 0 { if ret := C.git_repository_odb(&odb.ptr, v.ptr); ret < 0 {
return nil, LastError() return nil, LastError()
} }
@ -253,6 +291,9 @@ func (repo *Repository) SetWorkdir(workdir string, updateGitlink bool) error {
cstr := C.CString(workdir) cstr := C.CString(workdir)
defer C.free(unsafe.Pointer(cstr)) defer C.free(unsafe.Pointer(cstr))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if C.git_repository_set_workdir(repo.ptr, cstr, cbool(updateGitlink)) < 0 { if C.git_repository_set_workdir(repo.ptr, cstr, cbool(updateGitlink)) < 0 {
return LastError() return LastError()
} }
@ -261,9 +302,14 @@ func (repo *Repository) SetWorkdir(workdir string, updateGitlink bool) error {
func (v *Repository) TreeBuilder() (*TreeBuilder, error) { func (v *Repository) TreeBuilder() (*TreeBuilder, error) {
bld := new(TreeBuilder) bld := new(TreeBuilder)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if ret := C.git_treebuilder_create(&bld.ptr, nil); ret < 0 { if ret := C.git_treebuilder_create(&bld.ptr, nil); ret < 0 {
return nil, LastError() return nil, LastError()
} }
runtime.SetFinalizer(bld, (*TreeBuilder).Free)
bld.repo = v bld.repo = v
return bld, nil return bld, nil
@ -274,6 +320,10 @@ func (v *Repository) RevparseSingle(spec string) (Object, error) {
defer C.free(unsafe.Pointer(cspec)) defer C.free(unsafe.Pointer(cspec))
var ptr *C.git_object var ptr *C.git_object
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_revparse_single(&ptr, v.ptr, cspec) ecode := C.git_revparse_single(&ptr, v.ptr, cspec)
if ecode < 0 { if ecode < 0 {
return nil, LastError() return nil, LastError()

View File

@ -8,6 +8,7 @@ extern int _go_git_visit_submodule(git_repository *repo, void *fct);
*/ */
import "C" import "C"
import ( import (
"runtime"
"unsafe" "unsafe"
) )
@ -58,7 +59,8 @@ const (
type SubmoduleRecurse int type SubmoduleRecurse int
const ( const (
SubmoduleRecurseNo SubmoduleRecurse = C.GIT_SUBMODULE_RECURSE_NO SubmoduleRecurseReset SubmoduleRecurse = C.GIT_SUBMODULE_RECURSE_RESET
SubmoduleRecurseNo = C.GIT_SUBMODULE_RECURSE_NO
SubmoduleRecurseYes = C.GIT_SUBMODULE_RECURSE_YES SubmoduleRecurseYes = C.GIT_SUBMODULE_RECURSE_YES
SubmoduleRecurseOndemand = C.GIT_SUBMODULE_RECURSE_ONDEMAND SubmoduleRecurseOndemand = C.GIT_SUBMODULE_RECURSE_ONDEMAND
) )
@ -74,6 +76,10 @@ func (repo *Repository) LookupSubmodule(name string) (*Submodule, error) {
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
sub := new(Submodule) sub := new(Submodule)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_submodule_lookup(&sub.ptr, repo.ptr, cname) ret := C.git_submodule_lookup(&sub.ptr, repo.ptr, cname)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -92,6 +98,9 @@ func SubmoduleVisitor(csub unsafe.Pointer, name string, cfct unsafe.Pointer) int
} }
func (repo *Repository) ForeachSubmodule(cbk SubmoduleCbk) error { func (repo *Repository) ForeachSubmodule(cbk SubmoduleCbk) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C._go_git_visit_submodule(repo.ptr, unsafe.Pointer(&cbk)) ret := C._go_git_visit_submodule(repo.ptr, unsafe.Pointer(&cbk))
if ret < 0 { if ret < 0 {
return LastError() return LastError()
@ -106,6 +115,10 @@ func (repo *Repository) AddSubmodule(url, path string, use_git_link bool) (*Subm
defer C.free(unsafe.Pointer(cpath)) defer C.free(unsafe.Pointer(cpath))
sub := new(Submodule) sub := new(Submodule)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_submodule_add_setup(&sub.ptr, repo.ptr, curl, cpath, cbool(use_git_link)) ret := C.git_submodule_add_setup(&sub.ptr, repo.ptr, curl, cpath, cbool(use_git_link))
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -114,6 +127,9 @@ func (repo *Repository) AddSubmodule(url, path string, use_git_link bool) (*Subm
} }
func (sub *Submodule) FinalizeAdd() error { func (sub *Submodule) FinalizeAdd() error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_submodule_add_finalize(sub.ptr) ret := C.git_submodule_add_finalize(sub.ptr)
if ret < 0 { if ret < 0 {
return LastError() return LastError()
@ -122,6 +138,9 @@ func (sub *Submodule) FinalizeAdd() error {
} }
func (sub *Submodule) AddToIndex(write_index bool) error { func (sub *Submodule) AddToIndex(write_index bool) error {
runtime.LockOSThread()
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))
if ret < 0 { if ret < 0 {
return LastError() return LastError()
@ -130,6 +149,9 @@ func (sub *Submodule) AddToIndex(write_index bool) error {
} }
func (sub *Submodule) Save() error { func (sub *Submodule) Save() error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_submodule_save(sub.ptr) ret := C.git_submodule_save(sub.ptr)
if ret < 0 { if ret < 0 {
return LastError() return LastError()
@ -162,6 +184,9 @@ func (sub *Submodule) SetUrl(url string) error {
curl := C.CString(url) curl := C.CString(url)
defer C.free(unsafe.Pointer(curl)) defer C.free(unsafe.Pointer(curl))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_submodule_set_url(sub.ptr, curl) ret := C.git_submodule_set_url(sub.ptr, curl)
if ret < 0 { if ret < 0 {
return LastError() return LastError()
@ -229,6 +254,9 @@ func (sub *Submodule) SetFetchRecurseSubmodules(recurse SubmoduleRecurse) error
} }
func (sub *Submodule) Init(overwrite bool) error { func (sub *Submodule) Init(overwrite bool) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_submodule_init(sub.ptr, cbool(overwrite)) ret := C.git_submodule_init(sub.ptr, cbool(overwrite))
if ret < 0 { if ret < 0 {
return LastError() return LastError()
@ -237,6 +265,9 @@ func (sub *Submodule) Init(overwrite bool) error {
} }
func (sub *Submodule) Sync() error { func (sub *Submodule) Sync() error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_submodule_sync(sub.ptr) ret := C.git_submodule_sync(sub.ptr)
if ret < 0 { if ret < 0 {
return LastError() return LastError()
@ -246,6 +277,10 @@ func (sub *Submodule) Sync() error {
func (sub *Submodule) Open() (*Repository, error) { func (sub *Submodule) Open() (*Repository, error) {
repo := new(Repository) repo := new(Repository)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_submodule_open(&repo.ptr, sub.ptr) ret := C.git_submodule_open(&repo.ptr, sub.ptr)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -254,6 +289,9 @@ func (sub *Submodule) Open() (*Repository, error) {
} }
func (sub *Submodule) Reload() error { func (sub *Submodule) Reload() error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_submodule_reload(sub.ptr) ret := C.git_submodule_reload(sub.ptr)
if ret < 0 { if ret < 0 {
return LastError() return LastError()
@ -262,6 +300,9 @@ func (sub *Submodule) Reload() error {
} }
func (repo *Repository) ReloadAllSubmodules() error { func (repo *Repository) ReloadAllSubmodules() error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_submodule_reload_all(repo.ptr) ret := C.git_submodule_reload_all(repo.ptr)
if ret < 0 { if ret < 0 {
return LastError() return LastError()

16
tree.go
View File

@ -14,6 +14,7 @@ import (
) )
type Filemode int type Filemode int
const ( const (
FilemodeNew Filemode = C.GIT_FILEMODE_NEW FilemodeNew Filemode = C.GIT_FILEMODE_NEW
FilemodeTree = C.GIT_FILEMODE_TREE FilemodeTree = C.GIT_FILEMODE_TREE
@ -62,6 +63,9 @@ func (t Tree) EntryByPath(path string) (*TreeEntry, error) {
defer C.free(unsafe.Pointer(cpath)) defer C.free(unsafe.Pointer(cpath))
var entry *C.git_tree_entry var entry *C.git_tree_entry
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_tree_entry_bypath(&entry, t.ptr, cpath) ret := C.git_tree_entry_bypath(&entry, t.ptr, cpath)
if ret < 0 { if ret < 0 {
return nil, LastError() return nil, LastError()
@ -96,6 +100,9 @@ func CallbackGitTreeWalk(_root unsafe.Pointer, _entry unsafe.Pointer, ptr unsafe
} }
func (t Tree) Walk(callback TreeWalkCallback) error { func (t Tree) Walk(callback TreeWalkCallback) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
err := C._go_git_treewalk( err := C._go_git_treewalk(
t.ptr, t.ptr,
C.GIT_TREEWALK_PRE, C.GIT_TREEWALK_PRE,
@ -119,10 +126,13 @@ func (v *TreeBuilder) Free() {
C.git_treebuilder_free(v.ptr) C.git_treebuilder_free(v.ptr)
} }
func (v *TreeBuilder) Insert(filename string, id *Oid, filemode int) (error) { func (v *TreeBuilder) Insert(filename string, id *Oid, filemode int) error {
cfilename := C.CString(filename) cfilename := C.CString(filename)
defer C.free(unsafe.Pointer(cfilename)) defer C.free(unsafe.Pointer(cfilename))
runtime.LockOSThread()
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))
if err < 0 { if err < 0 {
return LastError() return LastError()
@ -133,6 +143,10 @@ func (v *TreeBuilder) Insert(filename string, id *Oid, filemode int) (error) {
func (v *TreeBuilder) Write() (*Oid, error) { func (v *TreeBuilder) Write() (*Oid, error) {
oid := new(Oid) oid := new(Oid)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
err := C.git_treebuilder_write(oid.toC(), v.repo.ptr, v.ptr) err := C.git_treebuilder_write(oid.toC(), v.repo.ptr, v.ptr)
if err < 0 { if err < 0 {

View File

@ -8,11 +8,13 @@ import "C"
import ( import (
"io" "io"
"runtime"
) )
// RevWalk // RevWalk
type SortType uint type SortType uint
const ( const (
SortNone SortType = C.GIT_SORT_NONE SortNone SortType = C.GIT_SORT_NONE
SortTopological = C.GIT_SORT_TOPOLOGICAL SortTopological = C.GIT_SORT_TOPOLOGICAL
@ -34,6 +36,9 @@ func (v *RevWalk) Push(id *Oid) {
} }
func (v *RevWalk) PushHead() (err error) { func (v *RevWalk) PushHead() (err error) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_revwalk_push_head(v.ptr) ecode := C.git_revwalk_push_head(v.ptr)
if ecode < 0 { if ecode < 0 {
err = LastError() err = LastError()
@ -43,6 +48,9 @@ func (v *RevWalk) PushHead() (err error) {
} }
func (v *RevWalk) Next(oid *Oid) (err error) { func (v *RevWalk) Next(oid *Oid) (err error) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_revwalk_next(oid.toC(), v.ptr) ret := C.git_revwalk_next(oid.toC(), v.ptr)
switch { switch {
case ret == ITEROVER: case ret == ITEROVER: