summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blob.go1
-rw-r--r--checkout.go8
-rw-r--r--commit.go22
-rw-r--r--config.go19
-rw-r--r--git.go32
-rw-r--r--index.go20
-rw-r--r--object.go3
-rw-r--r--odb.go25
-rw-r--r--odb_test.go27
-rw-r--r--packbuilder.go24
-rw-r--r--reference.go72
-rw-r--r--reference_test.go19
-rw-r--r--repository.go82
-rw-r--r--submodule.go63
-rw-r--r--tree.go13
-rw-r--r--walk.go8
16 files changed, 379 insertions, 59 deletions
diff --git a/blob.go b/blob.go
index cc26c92..b638c4f 100644
--- a/blob.go
+++ b/blob.go
@@ -1,7 +1,6 @@
package git
/*
-#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
*/
diff --git a/checkout.go b/checkout.go
index 92ced9e..f4c1d4e 100644
--- a/checkout.go
+++ b/checkout.go
@@ -1,7 +1,6 @@
package git
/*
-#cgo pkg-config: libgit2
#include <git2.h>
git_checkout_opts git_checkout_opts_init() {
git_checkout_opts ret = GIT_CHECKOUT_OPTS_INIT;
@@ -10,6 +9,7 @@ git_checkout_opts git_checkout_opts_init() {
*/
import "C"
import (
+ "runtime"
"os"
)
@@ -60,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()
@@ -73,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..0c64c76 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,15 @@ 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 {
+
+ if sig == nil {
+ return nil
+ }
+
var out *C.git_signature
name := C.CString(sig.Name)
diff --git a/config.go b/config.go
index ec8b8d0..2aa073a 100644
--- a/config.go
+++ b/config.go
@@ -1,12 +1,12 @@
package git
/*
-#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
*/
import "C"
import (
+ "runtime"
"unsafe"
)
@@ -19,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()
@@ -32,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()
@@ -45,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()
@@ -60,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()
@@ -67,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 6f81293..72ea33e 100644
--- a/git.go
+++ b/git.go
@@ -9,6 +9,7 @@ import "C"
import (
"bytes"
"errors"
+ "runtime"
"unsafe"
"strings"
)
@@ -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()
}
@@ -89,7 +93,7 @@ func (oid *Oid) Equal(oid2 *Oid) bool {
}
func (oid *Oid) IsZero() bool {
- for _, a := range(oid.bytes) {
+ for _, a := range oid.bytes {
if a != '0' {
return false
}
@@ -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())
@@ -123,10 +131,10 @@ func ShortenOids(ids []*Oid, minlen int) (int, error) {
type GitError struct {
Message string
- Code int
+ Code int
}
-func (e GitError) Error() string{
+func (e GitError) Error() string {
return e.Message
}
@@ -139,14 +147,14 @@ func LastError() error {
}
func cbool(b bool) C.int {
- if (b) {
+ if b {
return C.int(1)
}
return C.int(0)
}
func ucbool(b bool) C.uint {
- if (b) {
+ if b {
return C.uint(1)
}
return C.uint(0)
@@ -159,14 +167,16 @@ func Discover(start string, across_fs bool, ceiling_dirs []string) (string, erro
cstart := C.CString(start)
defer C.free(unsafe.Pointer(cstart))
- retpath := (*C.char)(C.malloc(C.GIT_PATH_MAX))
- defer C.free(unsafe.Pointer(retpath))
+ var buf C.git_buf
+ defer C.git_buf_free(&buf)
- r := C.git_repository_discover(retpath, C.GIT_PATH_MAX, cstart, cbool(across_fs), ceildirs)
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
- if r == 0 {
- return C.GoString(retpath), nil
+ ret := C.git_repository_discover(&buf, cstart, cbool(across_fs), ceildirs)
+ if ret < 0 {
+ return "", LastError()
}
- return "", LastError()
+ return C.GoString(buf.ptr), nil
}
diff --git a/index.go b/index.go
index 72b1d5b..fb32010 100644
--- a/index.go
+++ b/index.go
@@ -1,7 +1,6 @@
package git
/*
-#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
*/
@@ -25,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()
@@ -35,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()
@@ -43,6 +49,18 @@ func (v *Index) WriteTree() (*Oid, error) {
return oid, nil
}
+func (v *Index) Write() (error) {
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_index_write(v.ptr)
+ if ret < 0 {
+ return LastError()
+ }
+
+ return nil
+}
+
func (v *Index) Free() {
runtime.SetFinalizer(v, nil)
C.git_index_free(v.ptr)
diff --git a/object.go b/object.go
index 7b141aa..090be1f 100644
--- a/object.go
+++ b/object.go
@@ -1,7 +1,6 @@
package git
/*
-#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
*/
@@ -42,7 +41,7 @@ func (t ObjectType) String() (string) {
case ObjectBlob:
return "Blob"
case ObjectTag:
- return "tag"
+ return "Tag"
}
// Never reached
return ""
diff --git a/odb.go b/odb.go
index 3212bac..953791c 100644
--- a/odb.go
+++ b/odb.go
@@ -1,7 +1,6 @@
package git
/*
-#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
@@ -26,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 {
@@ -37,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()
@@ -72,6 +79,22 @@ func (v *Odb) ForEach() chan *Oid {
return ch
}
+// Hash determines the object-ID (sha1) of a data buffer.
+func (v *Odb) Hash(data []byte, otype ObjectType) (oid *Oid, err error) {
+ oid = new(Oid)
+ header := (*reflect.SliceHeader)(unsafe.Pointer(&data))
+ ptr := unsafe.Pointer(header.Data)
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_odb_hash(oid.toC(), ptr, C.size_t(header.Len), C.git_otype(otype));
+ if ret < 0 {
+ err = LastError()
+ }
+ return
+}
+
// NewReadStream opens a read stream from the ODB. Reading from it will give you the
// contents of the object.
func (v *Odb) NewReadStream(id *Oid) (*OdbReadStream, error) {
diff --git a/odb_test.go b/odb_test.go
index 3c7624c..a4f8943 100644
--- a/odb_test.go
+++ b/odb_test.go
@@ -32,4 +32,31 @@ func TestOdbStream(t *testing.T) {
if stream.Id.Cmp(expectedId) != 0 {
t.Fatal("Wrong data written")
}
+}
+
+func TestOdbHash(t *testing.T) {
+
+ repo := createTestRepo(t)
+ defer os.RemoveAll(repo.Workdir())
+ _, _ = seedTestRepo(t, repo)
+
+ odb, error := repo.Odb()
+ checkFatal(t, error)
+
+ str := `tree 115fcae49287c82eb55bb275cbbd4556fbed72b7
+parent 66e1c476199ebcd3e304659992233132c5a52c6c
+author John Doe <[email protected]> 1390682018 +0000
+committer John Doe <[email protected]> 1390682018 +0000
+
+Initial commit.`;
+
+ oid, error := odb.Hash([]byte(str), ObjectCommit)
+ checkFatal(t, error)
+
+ coid, error := odb.Write([]byte(str), ObjectCommit)
+ checkFatal(t, error)
+
+ if oid.Cmp(coid) != 0 {
+ t.Fatal("Hash and write Oids are different")
+ }
} \ No newline at end of file
diff --git a/packbuilder.go b/packbuilder.go
index bcb61a4..333f183 100644
--- a/packbuilder.go
+++ b/packbuilder.go
@@ -1,7 +1,6 @@
package git
/*
-#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
#include <git2/pack.h>
@@ -12,6 +11,7 @@ extern int _go_git_packbuilder_foreach(git_packbuilder *pb, void *payload);
import "C"
import (
"io"
+ "os"
"runtime"
"unsafe"
)
@@ -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()
@@ -65,10 +79,14 @@ func (pb *Packbuilder) ObjectCount() uint32 {
return uint32(C.git_packbuilder_object_count(pb.ptr))
}
-func (pb *Packbuilder) WriteToFile(name string) error {
+func (pb *Packbuilder) WriteToFile(name string, mode os.FileMode) error {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
- ret := C.git_packbuilder_write(pb.ptr, cname, nil, nil)
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_packbuilder_write(pb.ptr, cname, C.uint(mode.Perm()), nil, nil)
if ret != 0 {
return LastError()
}
diff --git a/reference.go b/reference.go
index 6ebe00f..a2f1636 100644
--- a/reference.go
+++ b/reference.go
@@ -1,7 +1,6 @@
package git
/*
-#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
*/
@@ -12,6 +11,7 @@ import (
)
type ReferenceType int
+
const (
ReferenceSymbolic ReferenceType = C.GIT_REF_SYMBOLIC
ReferenceOid = C.GIT_REF_OID
@@ -28,12 +28,22 @@ func newReferenceFromC(ptr *C.git_reference) *Reference {
return ref
}
-func (v *Reference) SetSymbolicTarget(target string) (*Reference, error) {
+func (v *Reference) SetSymbolicTarget(target string, sig *Signature, msg string) (*Reference, error) {
var ptr *C.git_reference
+
ctarget := C.CString(target)
defer C.free(unsafe.Pointer(ctarget))
- ret := C.git_reference_symbolic_set_target(&ptr, v.ptr, ctarget)
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ csig := sig.toC()
+ defer C.free(unsafe.Pointer(csig))
+
+ cmsg := C.CString(msg)
+ defer C.free(unsafe.Pointer(cmsg))
+
+ ret := C.git_reference_symbolic_set_target(&ptr, v.ptr, ctarget, csig, cmsg)
if ret < 0 {
return nil, LastError()
}
@@ -41,10 +51,19 @@ func (v *Reference) SetSymbolicTarget(target string) (*Reference, error) {
return newReferenceFromC(ptr), nil
}
-func (v *Reference) SetTarget(target *Oid) (*Reference, error) {
+func (v *Reference) SetTarget(target *Oid, sig *Signature, msg string) (*Reference, error) {
var ptr *C.git_reference
- ret := C.git_reference_set_target(&ptr, v.ptr, target.toC())
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ csig := sig.toC()
+ defer C.free(unsafe.Pointer(csig))
+
+ cmsg := C.CString(msg)
+ defer C.free(unsafe.Pointer(cmsg))
+
+ ret := C.git_reference_set_target(&ptr, v.ptr, target.toC(), csig, cmsg)
if ret < 0 {
return nil, LastError()
}
@@ -55,6 +74,9 @@ func (v *Reference) SetTarget(target *Oid) (*Reference, error) {
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()
@@ -63,12 +85,21 @@ 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, sig *Signature, msg 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))
+ csig := sig.toC()
+ defer C.free(unsafe.Pointer(csig))
+
+ cmsg := C.CString(msg)
+ defer C.free(unsafe.Pointer(cmsg))
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_reference_rename(&ptr, v.ptr, cname, cbool(force), csig, cmsg)
if ret < 0 {
return nil, LastError()
@@ -91,6 +122,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 {
@@ -108,6 +142,18 @@ func (v *Reference) Type() ReferenceType {
return ReferenceType(C.git_reference_type(v.ptr))
}
+func (v *Reference) IsBranch() bool {
+ return C.git_reference_is_branch(v.ptr) == 1
+}
+
+func (v *Reference) IsRemote() bool {
+ return C.git_reference_is_remote(v.ptr) == 1
+}
+
+func (v *Reference) IsTag() bool {
+ return C.git_reference_is_tag(v.ptr) == 1
+}
+
func (v *Reference) Free() {
runtime.SetFinalizer(v, nil)
C.git_reference_free(v.ptr)
@@ -121,6 +167,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()
@@ -138,6 +188,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()
@@ -152,6 +206,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 f955a2c..156960a 100644
--- a/reference_test.go
+++ b/reference_test.go
@@ -14,7 +14,14 @@ func TestRefModification(t *testing.T) {
commitId, treeId := seedTestRepo(t, repo)
- _, err := repo.CreateReference("refs/tags/tree", treeId, true)
+ loc, err := time.LoadLocation("Europe/Berlin")
+ checkFatal(t, err)
+ sig := &Signature{
+ Name: "Rand Om Hacker",
+ Email: "[email protected]",
+ When: time.Date(2013, 03, 06, 14, 30, 0, 0, loc),
+ }
+ _, err = repo.CreateReference("refs/tags/tree", treeId, true, sig, "testTreeTag")
checkFatal(t, err)
tag, err := repo.LookupReference("refs/tags/tree")
@@ -45,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, nil, "")
checkFatal(t, err)
tag, err = repo.LookupReference("refs/tags/renamed")
checkFatal(t, err)
@@ -78,13 +85,13 @@ func TestIterator(t *testing.T) {
commitId, err := repo.CreateCommit("HEAD", sig, sig, message, tree)
checkFatal(t, err)
- _, err = repo.CreateReference("refs/heads/one", commitId, true)
+ _, err = repo.CreateReference("refs/heads/one", commitId, true, sig, "headOne")
checkFatal(t, err)
- _, err = repo.CreateReference("refs/heads/two", commitId, true)
+ _, err = repo.CreateReference("refs/heads/two", commitId, true, sig, "headTwo")
checkFatal(t, err)
- _, err = repo.CreateReference("refs/heads/three", commitId, true)
+ _, err = repo.CreateReference("refs/heads/three", commitId, true, sig, "headThree")
checkFatal(t, err)
iter, err := repo.NewReferenceIterator()
@@ -108,7 +115,6 @@ func TestIterator(t *testing.T) {
t.Fatal("Iteration not over")
}
-
sort.Strings(list)
compareStringList(t, expected, list)
@@ -129,7 +135,6 @@ func TestIterator(t *testing.T) {
t.Fatalf("Wrong number of references returned %v", count)
}
-
// test the channel iteration
list = []string{}
iter, err = repo.NewReferenceIterator()
diff --git a/repository.go b/repository.go
index eec95dc..48c2b46 100644
--- a/repository.go
+++ b/repository.go
@@ -1,14 +1,13 @@
package git
/*
-#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
*/
import "C"
import (
- "unsafe"
"runtime"
+ "unsafe"
)
// Repository
@@ -22,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()
@@ -37,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()
@@ -54,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()
@@ -74,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()
@@ -118,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()
@@ -126,12 +146,22 @@ func (v *Repository) LookupReference(name string) (*Reference, error) {
return newReferenceFromC(ptr), nil
}
-func (v *Repository) CreateReference(name string, oid *Oid, force bool) (*Reference, error) {
+func (v *Repository) CreateReference(name string, oid *Oid, force bool, sig *Signature, msg string) (*Reference, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
+
+ csig := sig.toC()
+ defer C.free(unsafe.Pointer(csig))
+
+ cmsg := C.CString(msg)
+ defer C.free(unsafe.Pointer(cmsg))
+
var ptr *C.git_reference
- ecode := C.git_reference_create(&ptr, v.ptr, cname, oid.toC(), cbool(force))
+ 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()
}
@@ -139,14 +169,25 @@ func (v *Repository) CreateReference(name string, oid *Oid, force bool) (*Refere
return newReferenceFromC(ptr), nil
}
-func (v *Repository) CreateSymbolicReference(name, target string, force bool) (*Reference, error) {
+func (v *Repository) CreateSymbolicReference(name, target string, force bool, sig *Signature, msg string) (*Reference, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
+
ctarget := C.CString(target)
defer C.free(unsafe.Pointer(ctarget))
+
+ csig := sig.toC()
+ defer C.free(unsafe.Pointer(csig))
+
+ cmsg := C.CString(msg)
+ defer C.free(unsafe.Pointer(cmsg))
+
var ptr *C.git_reference
- ecode := C.git_reference_symbolic_create(&ptr, v.ptr, cname, ctarget, cbool(force))
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ecode := C.git_reference_symbolic_create(&ptr, v.ptr, cname, ctarget, cbool(force), csig, cmsg)
if ecode < 0 {
return nil, LastError()
}
@@ -156,6 +197,10 @@ func (v *Repository) CreateSymbolicReference(name, target string, force bool) (*
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()
@@ -181,7 +226,7 @@ func (v *Repository) CreateCommit(
var cparents []*C.git_commit = nil
var parentsarg **C.git_commit = nil
- nparents:= len(parents)
+ nparents := len(parents)
if nparents > 0 {
cparents = make([]*C.git_commit, nparents)
for i, v := range parents {
@@ -196,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()
@@ -215,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()
}
@@ -227,7 +279,7 @@ func (repo *Repository) Path() string {
return C.GoString(C.git_repository_path(repo.ptr))
}
-func (repo *Repository) IsBare() (bool) {
+func (repo *Repository) IsBare() bool {
return C.git_repository_is_bare(repo.ptr) != 0
}
@@ -239,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()
}
@@ -247,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
@@ -260,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 901f172..9abf333 100644
--- a/submodule.go
+++ b/submodule.go
@@ -1,7 +1,6 @@
package git
/*
-#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
@@ -9,6 +8,7 @@ extern int _go_git_visit_submodule(git_repository *repo, void *fct);
*/
import "C"
import (
+ "runtime"
"unsafe"
)
@@ -56,6 +56,14 @@ const (
SubmoduleStatusWdUntracked = C.GIT_SUBMODULE_STATUS_WD_UNTRACKED
)
+type SubmoduleRecurse int
+
+const (
+ SubmoduleRecurseNo SubmoduleRecurse = C.GIT_SUBMODULE_RECURSE_NO
+ SubmoduleRecurseYes = C.GIT_SUBMODULE_RECURSE_YES
+ SubmoduleRecurseOndemand = C.GIT_SUBMODULE_RECURSE_ONDEMAND
+)
+
func SubmoduleStatusIsUnmodified(status int) bool {
o := SubmoduleStatus(status) & ^(SubmoduleStatusInHead | SubmoduleStatusInIndex |
SubmoduleStatusInConfig | SubmoduleStatusInWd)
@@ -67,6 +75,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()
@@ -85,6 +97,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()
@@ -99,6 +114,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()
@@ -107,6 +126,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()
@@ -115,6 +137,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()
@@ -123,6 +148,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()
@@ -155,6 +183,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()
@@ -206,15 +237,15 @@ func (sub *Submodule) SetUpdate(update SubmoduleUpdate) SubmoduleUpdate {
return SubmoduleUpdate(o)
}
-func (sub *Submodule) FetchRecurseSubmodules() bool {
- if 0 == C.git_submodule_fetch_recurse_submodules(sub.ptr) {
- return false
- }
- return true
+func (sub *Submodule) FetchRecurseSubmodules() SubmoduleRecurse {
+ return SubmoduleRecurse(C.git_submodule_fetch_recurse_submodules(sub.ptr));
}
-func (sub *Submodule) SetFetchRecurseSubmodules(v bool) error {
- ret := C.git_submodule_set_fetch_recurse_submodules(sub.ptr, cbool(v))
+func (sub *Submodule) SetFetchRecurseSubmodules(recurse SubmoduleRecurse) error {
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_submodule_set_fetch_recurse_submodules(sub.ptr, C.git_submodule_recurse_t(recurse))
if ret < 0 {
return LastError()
}
@@ -222,6 +253,9 @@ func (sub *Submodule) SetFetchRecurseSubmodules(v bool) 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()
@@ -230,6 +264,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()
@@ -239,6 +276,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()
@@ -247,6 +288,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()
@@ -255,6 +299,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..8c74e5d 100644
--- a/tree.go
+++ b/tree.go
@@ -62,6 +62,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 +99,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,
@@ -123,6 +129,9 @@ 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 +142,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 6525db1..6979b6b 100644
--- a/walk.go
+++ b/walk.go
@@ -1,7 +1,6 @@
package git
/*
-#cgo pkg-config: libgit2
#include <git2.h>
#include <git2/errors.h>
*/
@@ -9,6 +8,7 @@ import "C"
import (
"io"
+ "runtime"
)
// RevWalk
@@ -35,6 +35,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()
@@ -44,6 +47,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: