diff --git a/blob.go b/blob.go index b638c4f..c182e54 100644 --- a/blob.go +++ b/blob.go @@ -22,4 +22,3 @@ func (v Blob) Contents() []byte { buffer := unsafe.Pointer(C.git_blob_rawcontent(v.ptr)) return C.GoBytes(buffer, size) } - diff --git a/checkout.go b/checkout.go index 63637e2..e3471a0 100644 --- a/checkout.go +++ b/checkout.go @@ -10,6 +10,7 @@ git_checkout_opts git_checkout_opts_init() { import "C" import ( "os" + "runtime" ) type CheckoutStrategy uint @@ -35,10 +36,10 @@ const ( type CheckoutOpts struct { Strategy CheckoutStrategy // Default will be a dry run - DisableFilters bool // Don't apply filters like CRLF conversion - DirMode os.FileMode // Default is 0755 - FileMode os.FileMode // Default is 0644 or 0755 as dictated by blob - FileOpenFlags int // Default is O_CREAT | O_TRUNC | O_WRONLY + DisableFilters bool // Don't apply filters like CRLF conversion + DirMode os.FileMode // Default is 0755 + FileMode os.FileMode // Default is 0644 or 0755 as dictated by blob + FileOpenFlags int // Default is O_CREAT | O_TRUNC | O_WRONLY } // Convert the CheckoutOpts struct to the corresponding C-struct @@ -59,6 +60,9 @@ func (v *Repository) Checkout(opts *CheckoutOpts) error { var copts C.git_checkout_opts populateCheckoutOpts(&copts, opts) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_checkout_head(v.ptr, &copts) if ret < 0 { return LastError() @@ -72,6 +76,9 @@ func (v *Repository) CheckoutIndex(index *Index, opts *CheckoutOpts) error { var copts C.git_checkout_opts populateCheckoutOpts(&copts, opts) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_checkout_index(v.ptr, index.ptr, &copts) if ret < 0 { return LastError() diff --git a/commit.go b/commit.go index cacaa33..498669e 100644 --- a/commit.go +++ b/commit.go @@ -9,8 +9,9 @@ extern int _go_git_treewalk(git_tree *tree, git_treewalk_mode mode, void *ptr); import "C" import ( - "unsafe" + "runtime" "time" + "unsafe" ) // Commit @@ -25,6 +26,9 @@ func (c Commit) Message() string { func (c Commit) Tree() (*Tree, error) { var ptr *C.git_object + runtime.LockOSThread() + defer runtime.UnlockOSThread() + err := C.git_commit_tree(&ptr, c.ptr) if err < 0 { return nil, LastError() @@ -48,12 +52,13 @@ func (c Commit) Committer() *Signature { } func (c *Commit) Parent(n uint) *Commit { - par := &Commit{} - ret := C.git_commit_parent(&par.ptr, c.ptr, C.uint(n)) + var cobj *C.git_object + ret := C.git_commit_parent(&cobj, c.ptr, C.uint(n)) if ret != 0 { return nil } - return par + + return allocObject(cobj).(*Commit) } 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 func (v *Signature) Offset() int { _, 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 name := C.CString(sig.Name) diff --git a/config.go b/config.go index dcad2a7..2aa073a 100644 --- a/config.go +++ b/config.go @@ -6,6 +6,7 @@ package git */ import "C" import ( + "runtime" "unsafe" ) @@ -18,6 +19,9 @@ func (c *Config) LookupInt32(name string) (v int32, err error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_config_get_int32(&out, c.ptr, cname) if ret < 0 { return 0, LastError() @@ -31,6 +35,9 @@ func (c *Config) LookupInt64(name string) (v int64, err error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_config_get_int64(&out, c.ptr, cname) if ret < 0 { return 0, LastError() @@ -44,6 +51,9 @@ func (c *Config) LookupString(name string) (v string, err error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_config_get_string(&ptr, c.ptr, cname) if ret < 0 { return "", LastError() @@ -59,6 +69,9 @@ func (c *Config) Set(name, value string) (err error) { cvalue := C.CString(value) defer C.free(unsafe.Pointer(cvalue)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_config_set_string(c.ptr, cname, cvalue) if ret < 0 { return LastError() @@ -66,3 +79,8 @@ func (c *Config) Set(name, value string) (err error) { return nil } + +func (c *Config) Free() { + runtime.SetFinalizer(c, nil) + C.git_config_free(c.ptr) +} diff --git a/git.go b/git.go index c663d2e..406ecb7 100644 --- a/git.go +++ b/git.go @@ -9,6 +9,7 @@ import "C" import ( "bytes" "errors" + "runtime" "strings" "unsafe" ) @@ -57,6 +58,9 @@ func NewOidFromString(s string) (*Oid, error) { cs := C.CString(s) defer C.free(unsafe.Pointer(cs)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + if C.git_oid_fromstr(o.toC(), cs) < 0 { return nil, LastError() } @@ -109,6 +113,10 @@ func ShortenOids(ids []*Oid, minlen int) (int, error) { defer C.git_oid_shorten_free(shorten) var ret C.int + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + for _, id := range ids { buf := make([]byte, 41) 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)) defer C.git_buf_free(retpath) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + r := C.git_repository_discover(retpath, cstart, cbool(across_fs), ceildirs) if r == 0 { diff --git a/git_test.go b/git_test.go index 52aea1d..5534240 100644 --- a/git_test.go +++ b/git_test.go @@ -1,8 +1,8 @@ package git import ( - "testing" "io/ioutil" + "testing" "time" ) @@ -14,7 +14,7 @@ func createTestRepo(t *testing.T) *Repository { checkFatal(t, err) tmpfile := "README" - err = ioutil.WriteFile(path + "/" + tmpfile, []byte("foo\n"), 0644) + err = ioutil.WriteFile(path+"/"+tmpfile, []byte("foo\n"), 0644) checkFatal(t, err) return repo @@ -44,4 +44,3 @@ func seedTestRepo(t *testing.T, repo *Repository) (*Oid, *Oid) { return commitId, treeId } - diff --git a/index.go b/index.go index 4a69c1e..ac5148c 100644 --- a/index.go +++ b/index.go @@ -24,6 +24,9 @@ func (v *Index) AddByPath(path string) error { cstr := C.CString(path) defer C.free(unsafe.Pointer(cstr)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_index_add_bypath(v.ptr, cstr) if ret < 0 { return LastError() @@ -34,6 +37,10 @@ func (v *Index) AddByPath(path string) error { func (v *Index) WriteTree() (*Oid, error) { oid := new(Oid) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_index_write_tree(oid.toC(), v.ptr) if ret < 0 { return nil, LastError() diff --git a/object.go b/object.go index 090be1f..7834a1a 100644 --- a/object.go +++ b/object.go @@ -10,12 +10,12 @@ import "runtime" type ObjectType int const ( - ObjectAny ObjectType = C.GIT_OBJ_ANY - ObjectBad = C.GIT_OBJ_BAD - ObjectCommit = C.GIT_OBJ_COMMIT - ObjectTree = C.GIT_OBJ_TREE - ObjectBlob = C.GIT_OBJ_BLOB - ObjectTag = C.GIT_OBJ_TAG + ObjectAny ObjectType = C.GIT_OBJ_ANY + ObjectBad = C.GIT_OBJ_BAD + ObjectCommit = C.GIT_OBJ_COMMIT + ObjectTree = C.GIT_OBJ_TREE + ObjectBlob = C.GIT_OBJ_BLOB + ObjectTag = C.GIT_OBJ_TAG ) type Object interface { @@ -28,8 +28,8 @@ type gitObject struct { ptr *C.git_object } -func (t ObjectType) String() (string) { - switch (t) { +func (t ObjectType) String() string { + switch t { case ObjectAny: return "Any" case ObjectBad: diff --git a/odb.go b/odb.go index eaa7872..d5a54ac 100644 --- a/odb.go +++ b/odb.go @@ -8,9 +8,9 @@ extern int _go_git_odb_foreach(git_odb *db, void *payload); */ import "C" import ( - "unsafe" "reflect" "runtime" + "unsafe" ) 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) { oid = new(Oid) 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)) 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) { obj = new(OdbObject) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_odb_read(&obj.ptr, v.ptr, oid.toC()) if ret < 0 { return nil, LastError() @@ -55,9 +63,9 @@ func odbForEachCb(id *C.git_oid, payload unsafe.Pointer) int { select { case ch <- oid: case <-ch: - return -1 + return -1 } - return 0; + return 0 } func (v *Odb) forEachWrap(ch chan *Oid) { @@ -161,7 +169,7 @@ func (stream *OdbReadStream) Free() { type OdbWriteStream struct { ptr *C.git_odb_stream - Id Oid + Id Oid } // Write writes to the stream diff --git a/odb_test.go b/odb_test.go index 3c7624c..fded782 100644 --- a/odb_test.go +++ b/odb_test.go @@ -32,4 +32,4 @@ func TestOdbStream(t *testing.T) { if stream.Id.Cmp(expectedId) != 0 { t.Fatal("Wrong data written") } -} \ No newline at end of file +} diff --git a/packbuilder.go b/packbuilder.go index c57b0d4..e628bd1 100644 --- a/packbuilder.go +++ b/packbuilder.go @@ -22,6 +22,10 @@ type Packbuilder struct { func (repo *Repository) NewPackbuilder() (*Packbuilder, error) { builder := &Packbuilder{} + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_packbuilder_new(&builder.ptr, repo.ptr) if ret != 0 { return nil, LastError() @@ -38,6 +42,10 @@ func (pb *Packbuilder) Free() { func (pb *Packbuilder) Insert(id *Oid, name string) error { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_packbuilder_insert(pb.ptr, id.toC(), cname) if ret != 0 { return LastError() @@ -46,6 +54,9 @@ func (pb *Packbuilder) Insert(id *Oid, name string) error { } func (pb *Packbuilder) InsertCommit(id *Oid) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_packbuilder_insert_commit(pb.ptr, id.toC()) if ret != 0 { return LastError() @@ -54,6 +65,9 @@ func (pb *Packbuilder) InsertCommit(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()) if ret != 0 { return LastError() @@ -68,6 +82,10 @@ func (pb *Packbuilder) ObjectCount() uint32 { func (pb *Packbuilder) WriteToFile(name string, mode os.FileMode) error { cname := C.CString(name) 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) if ret != 0 { return LastError() @@ -92,7 +110,7 @@ func (pb *Packbuilder) Written() uint32 { } type packbuilderCbData struct { - ch chan<- []byte + ch chan<- []byte stop <-chan bool } @@ -104,7 +122,7 @@ func packbuilderForEachCb(buf unsafe.Pointer, size C.size_t, payload unsafe.Poin slice := C.GoBytes(buf, C.int(size)) select { - case <- stop: + case <-stop: return -1 case ch <- slice: } diff --git a/reference.go b/reference.go index 8060146..e067aa7 100644 --- a/reference.go +++ b/reference.go @@ -40,6 +40,9 @@ func (v *Reference) SetSymbolicTarget(target string, sig *Signature, msg string) cmsg := C.CString(msg) defer C.free(unsafe.Pointer(cmsg)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_reference_symbolic_set_target(&ptr, v.ptr, ctarget, csig, cmsg) if ret < 0 { return nil, LastError() @@ -68,6 +71,9 @@ func (v *Reference) SetTarget(target *Oid, sig *Signature, msg string) (*Referen func (v *Reference) Resolve() (*Reference, error) { var ptr *C.git_reference + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_reference_resolve(&ptr, v.ptr) if ret < 0 { return nil, LastError() @@ -76,12 +82,18 @@ func (v *Reference) Resolve() (*Reference, error) { 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 cname := C.CString(name) 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 { return nil, LastError() @@ -104,6 +116,9 @@ func (v *Reference) SymbolicTarget() string { } func (v *Reference) Delete() error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_reference_delete(v.ptr) if ret < 0 { @@ -134,6 +149,10 @@ type ReferenceIterator struct { // NewReferenceIterator creates a new iterator over reference names func (repo *Repository) NewReferenceIterator() (*ReferenceIterator, error) { var ptr *C.git_reference_iterator + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_reference_iterator_new(&ptr, repo.ptr) if ret < 0 { return nil, LastError() @@ -151,6 +170,10 @@ func (repo *Repository) NewReferenceIteratorGlob(glob string) (*ReferenceIterato cstr := C.CString(glob) defer C.free(unsafe.Pointer(cstr)) var ptr *C.git_reference_iterator + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_reference_iterator_glob_new(&ptr, repo.ptr, cstr) if ret < 0 { return nil, LastError() @@ -165,6 +188,10 @@ func (repo *Repository) NewReferenceIteratorGlob(glob string) (*ReferenceIterato // the returned error is git.ErrIterOver func (v *ReferenceIterator) NextName() (string, error) { var ptr *C.char + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_reference_next_name(&ptr, v.ptr) if ret == ITEROVER { return "", ErrIterOver diff --git a/reference_test.go b/reference_test.go index ab62522..dd0c75d 100644 --- a/reference_test.go +++ b/reference_test.go @@ -52,7 +52,7 @@ func TestRefModification(t *testing.T) { t.Fatalf("Wrong ref target") } - _, err = tag.Rename("refs/tags/renamed", false) + _, err = tag.Rename("refs/tags/renamed", false, "") checkFatal(t, err) tag, err = repo.LookupReference("refs/tags/renamed") checkFatal(t, err) diff --git a/repository.go b/repository.go index 31a2d05..27f200e 100644 --- a/repository.go +++ b/repository.go @@ -21,6 +21,9 @@ func OpenRepository(path string) (*Repository, error) { cpath := C.CString(path) defer C.free(unsafe.Pointer(cpath)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_repository_open(&repo.ptr, cpath) if ret < 0 { return nil, LastError() @@ -36,6 +39,9 @@ func InitRepository(path string, isbare bool) (*Repository, error) { cpath := C.CString(path) defer C.free(unsafe.Pointer(cpath)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_repository_init(&repo.ptr, cpath, ucbool(isbare)) if ret < 0 { return nil, LastError() @@ -53,16 +59,24 @@ func (v *Repository) Free() { func (v *Repository) Config() (*Config, error) { config := new(Config) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_repository_config(&config.ptr, v.ptr) if ret < 0 { return nil, LastError() } + runtime.SetFinalizer(config, (*Config).Free) return config, nil } func (v *Repository) Index() (*Index, error) { var ptr *C.git_index + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_repository_index(&ptr, v.ptr) if ret < 0 { return nil, LastError() @@ -73,6 +87,10 @@ func (v *Repository) Index() (*Index, error) { func (v *Repository) lookupType(oid *Oid, t ObjectType) (Object, error) { var ptr *C.git_object + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_object_lookup(&ptr, v.ptr, oid.toC(), C.git_otype(t)) if ret < 0 { return nil, LastError() @@ -117,6 +135,9 @@ func (v *Repository) LookupReference(name string) (*Reference, error) { defer C.free(unsafe.Pointer(cname)) var ptr *C.git_reference + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ecode := C.git_reference_lookup(&ptr, v.ptr, cname) if ecode < 0 { return nil, LastError() @@ -137,6 +158,9 @@ func (v *Repository) CreateReference(name string, oid *Oid, force bool, sig *Sig 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) if ecode < 0 { return nil, LastError() @@ -158,6 +182,9 @@ func (v *Repository) CreateSymbolicReference(name, target string, force bool, si cmsg := C.CString(msg) defer C.free(unsafe.Pointer(cmsg)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + var ptr *C.git_reference 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) { walk := new(RevWalk) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ecode := C.git_revwalk_new(&walk.ptr, v.ptr) if ecode < 0 { return nil, LastError() @@ -210,10 +241,13 @@ func (v *Repository) CreateCommit( committerSig := committer.toC() defer C.git_signature_free(committerSig) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_commit_create( oid.toC(), v.ptr, cref, authorSig, committerSig, - nil, cmsg, tree.ptr, C.int(nparents), parentsarg) + nil, cmsg, tree.ptr, C.size_t(nparents), parentsarg) if ret < 0 { return nil, LastError() @@ -229,6 +263,10 @@ func (v *Odb) Free() { func (v *Repository) Odb() (odb *Odb, err error) { odb = new(Odb) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + if ret := C.git_repository_odb(&odb.ptr, v.ptr); ret < 0 { return nil, LastError() } @@ -253,6 +291,9 @@ func (repo *Repository) SetWorkdir(workdir string, updateGitlink bool) error { cstr := C.CString(workdir) defer C.free(unsafe.Pointer(cstr)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + if C.git_repository_set_workdir(repo.ptr, cstr, cbool(updateGitlink)) < 0 { return LastError() } @@ -261,9 +302,14 @@ func (repo *Repository) SetWorkdir(workdir string, updateGitlink bool) error { func (v *Repository) TreeBuilder() (*TreeBuilder, error) { bld := new(TreeBuilder) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + if ret := C.git_treebuilder_create(&bld.ptr, nil); ret < 0 { return nil, LastError() } + runtime.SetFinalizer(bld, (*TreeBuilder).Free) bld.repo = v return bld, nil @@ -274,6 +320,10 @@ func (v *Repository) RevparseSingle(spec string) (Object, error) { defer C.free(unsafe.Pointer(cspec)) var ptr *C.git_object + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ecode := C.git_revparse_single(&ptr, v.ptr, cspec) if ecode < 0 { return nil, LastError() diff --git a/submodule.go b/submodule.go index 903d784..cf422d2 100644 --- a/submodule.go +++ b/submodule.go @@ -8,6 +8,7 @@ extern int _go_git_visit_submodule(git_repository *repo, void *fct); */ import "C" import ( + "runtime" "unsafe" ) @@ -58,7 +59,8 @@ const ( type SubmoduleRecurse int 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 SubmoduleRecurseOndemand = C.GIT_SUBMODULE_RECURSE_ONDEMAND ) @@ -74,6 +76,10 @@ func (repo *Repository) LookupSubmodule(name string) (*Submodule, error) { defer C.free(unsafe.Pointer(cname)) sub := new(Submodule) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_submodule_lookup(&sub.ptr, repo.ptr, cname) if ret < 0 { 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 { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C._go_git_visit_submodule(repo.ptr, unsafe.Pointer(&cbk)) if ret < 0 { return LastError() @@ -106,6 +115,10 @@ func (repo *Repository) AddSubmodule(url, path string, use_git_link bool) (*Subm defer C.free(unsafe.Pointer(cpath)) sub := new(Submodule) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_submodule_add_setup(&sub.ptr, repo.ptr, curl, cpath, cbool(use_git_link)) if ret < 0 { return nil, LastError() @@ -114,6 +127,9 @@ func (repo *Repository) AddSubmodule(url, path string, use_git_link bool) (*Subm } func (sub *Submodule) FinalizeAdd() error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_submodule_add_finalize(sub.ptr) if ret < 0 { return LastError() @@ -122,6 +138,9 @@ func (sub *Submodule) FinalizeAdd() 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)) if ret < 0 { return LastError() @@ -130,6 +149,9 @@ func (sub *Submodule) AddToIndex(write_index bool) error { } func (sub *Submodule) Save() error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_submodule_save(sub.ptr) if ret < 0 { return LastError() @@ -162,6 +184,9 @@ func (sub *Submodule) SetUrl(url string) error { curl := C.CString(url) defer C.free(unsafe.Pointer(curl)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_submodule_set_url(sub.ptr, curl) if ret < 0 { return LastError() @@ -229,6 +254,9 @@ func (sub *Submodule) SetFetchRecurseSubmodules(recurse SubmoduleRecurse) error } func (sub *Submodule) Init(overwrite bool) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_submodule_init(sub.ptr, cbool(overwrite)) if ret < 0 { return LastError() @@ -237,6 +265,9 @@ func (sub *Submodule) Init(overwrite bool) error { } func (sub *Submodule) Sync() error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_submodule_sync(sub.ptr) if ret < 0 { return LastError() @@ -246,6 +277,10 @@ func (sub *Submodule) Sync() error { func (sub *Submodule) Open() (*Repository, error) { repo := new(Repository) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_submodule_open(&repo.ptr, sub.ptr) if ret < 0 { return nil, LastError() @@ -254,6 +289,9 @@ func (sub *Submodule) Open() (*Repository, error) { } func (sub *Submodule) Reload() error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_submodule_reload(sub.ptr) if ret < 0 { return LastError() @@ -262,6 +300,9 @@ func (sub *Submodule) Reload() error { } func (repo *Repository) ReloadAllSubmodules() error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_submodule_reload_all(repo.ptr) if ret < 0 { return LastError() diff --git a/tree.go b/tree.go index 3abd31c..2e7eae6 100644 --- a/tree.go +++ b/tree.go @@ -14,13 +14,14 @@ import ( ) type Filemode int + const ( - FilemodeNew Filemode = C.GIT_FILEMODE_NEW - FilemodeTree = C.GIT_FILEMODE_TREE - FilemodeBlob = C.GIT_FILEMODE_BLOB - FilemodeBlobExecutable = C.GIT_FILEMODE_BLOB_EXECUTABLE - FilemodeLink = C.GIT_FILEMODE_LINK - FilemodeCommit = C.GIT_FILEMODE_COMMIT + FilemodeNew Filemode = C.GIT_FILEMODE_NEW + FilemodeTree = C.GIT_FILEMODE_TREE + FilemodeBlob = C.GIT_FILEMODE_BLOB + FilemodeBlobExecutable = C.GIT_FILEMODE_BLOB_EXECUTABLE + FilemodeLink = C.GIT_FILEMODE_LINK + FilemodeCommit = C.GIT_FILEMODE_COMMIT ) type Tree struct { @@ -28,9 +29,9 @@ type Tree struct { } type TreeEntry struct { - Name string - Id *Oid - Type ObjectType + Name string + Id *Oid + Type ObjectType Filemode int } @@ -62,6 +63,9 @@ func (t Tree) EntryByPath(path string) (*TreeEntry, error) { defer C.free(unsafe.Pointer(cpath)) var entry *C.git_tree_entry + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_tree_entry_bypath(&entry, t.ptr, cpath) if ret < 0 { return nil, LastError() @@ -96,6 +100,9 @@ func CallbackGitTreeWalk(_root unsafe.Pointer, _entry unsafe.Pointer, ptr unsafe } func (t Tree) Walk(callback TreeWalkCallback) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + err := C._go_git_treewalk( t.ptr, C.GIT_TREEWALK_PRE, @@ -110,7 +117,7 @@ func (t Tree) Walk(callback TreeWalkCallback) error { } type TreeBuilder struct { - ptr *C.git_treebuilder + ptr *C.git_treebuilder repo *Repository } @@ -119,10 +126,13 @@ func (v *TreeBuilder) Free() { 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) 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)) if err < 0 { return LastError() @@ -133,6 +143,10 @@ func (v *TreeBuilder) Insert(filename string, id *Oid, filemode int) (error) { func (v *TreeBuilder) Write() (*Oid, error) { oid := new(Oid) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + err := C.git_treebuilder_write(oid.toC(), v.repo.ptr, v.ptr) if err < 0 { diff --git a/walk.go b/walk.go index 9fc4094..6f702f1 100644 --- a/walk.go +++ b/walk.go @@ -8,16 +8,18 @@ import "C" import ( "io" + "runtime" ) // RevWalk type SortType uint + const ( - SortNone SortType = C.GIT_SORT_NONE - SortTopological = C.GIT_SORT_TOPOLOGICAL - SortTime = C.GIT_SORT_TIME - SortReverse = C.GIT_SORT_REVERSE + SortNone SortType = C.GIT_SORT_NONE + SortTopological = C.GIT_SORT_TOPOLOGICAL + SortTime = C.GIT_SORT_TIME + SortReverse = C.GIT_SORT_REVERSE ) type RevWalk struct { @@ -34,6 +36,9 @@ func (v *RevWalk) Push(id *Oid) { } func (v *RevWalk) PushHead() (err error) { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ecode := C.git_revwalk_push_head(v.ptr) if ecode < 0 { err = LastError() @@ -43,6 +48,9 @@ func (v *RevWalk) PushHead() (err error) { } func (v *RevWalk) Next(oid *Oid) (err error) { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_revwalk_next(oid.toC(), v.ptr) switch { case ret == ITEROVER: