diff --git a/commit.go b/commit.go index 498669e..0c64c76 100644 --- a/commit.go +++ b/commit.go @@ -94,6 +94,11 @@ func (v *Signature) Offset() int { } 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/git.go b/git.go index 406ecb7..72ea33e 100644 --- a/git.go +++ b/git.go @@ -10,8 +10,8 @@ import ( "bytes" "errors" "runtime" - "strings" "unsafe" + "strings" ) const ( @@ -167,17 +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.git_buf)(C.malloc(C.GIT_PATH_MAX)) - defer C.git_buf_free(retpath) + var buf C.git_buf + defer C.git_buf_free(&buf) runtime.LockOSThread() defer runtime.UnlockOSThread() - r := C.git_repository_discover(retpath, cstart, cbool(across_fs), ceildirs) - - if r == 0 { - return C.GoString(retpath.ptr), 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 ac5148c..fb32010 100644 --- a/index.go +++ b/index.go @@ -49,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/odb.go b/odb.go index fc8fbd4..4a5187c 100644 --- a/odb.go +++ b/odb.go @@ -110,6 +110,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 1390682018 +0000 +committer John Doe 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/reference.go b/reference.go index 207b1b2..a2f1636 100644 --- a/reference.go +++ b/reference.go @@ -34,6 +34,9 @@ func (v *Reference) SetSymbolicTarget(target string, sig *Signature, msg string) ctarget := C.CString(target) defer C.free(unsafe.Pointer(ctarget)) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + csig := sig.toC() defer C.free(unsafe.Pointer(csig)) @@ -41,7 +44,6 @@ func (v *Reference) SetSymbolicTarget(target string, sig *Signature, msg string) 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() } @@ -52,6 +54,9 @@ func (v *Reference) SetSymbolicTarget(target string, sig *Signature, msg string) func (v *Reference) SetTarget(target *Oid, sig *Signature, msg string) (*Reference, error) { var ptr *C.git_reference + runtime.LockOSThread() + defer runtime.UnlockOSThread() + csig := sig.toC() defer C.free(unsafe.Pointer(csig)) @@ -59,7 +64,6 @@ func (v *Reference) SetTarget(target *Oid, sig *Signature, msg string) (*Referen 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() } @@ -81,15 +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)) + 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)) + ret := C.git_reference_rename(&ptr, v.ptr, cname, cbool(force), csig, cmsg) if ret < 0 { return nil, LastError() @@ -132,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) diff --git a/reference_test.go b/reference_test.go index ab62522..156960a 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, nil, "") checkFatal(t, err) tag, err = repo.LookupReference("refs/tags/renamed") checkFatal(t, err) diff --git a/repository.go b/repository.go index f8b327a..6fbf1d3 100644 --- a/repository.go +++ b/repository.go @@ -179,8 +179,10 @@ func (v *Repository) CreateReference(name string, oid *Oid, force bool, sig *Sig var ptr *C.git_reference - ecode := C.git_reference_create(&ptr, v.ptr, cname, oid.toC(), cbool(force), csig, cmsg) + 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() } @@ -203,8 +205,10 @@ func (v *Repository) CreateSymbolicReference(name, target string, force bool, si var ptr *C.git_reference - ecode := C.git_reference_symbolic_create(&ptr, v.ptr, cname, ctarget, cbool(force), csig, cmsg) + 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() } @@ -264,7 +268,7 @@ func (v *Repository) CreateCommit( 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() diff --git a/submodule.go b/submodule.go index aed5316..9abf333 100644 --- a/submodule.go +++ b/submodule.go @@ -237,16 +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(recurse SubmoduleRecurse) error { - ret := C.git_submodule_set_fetch_recurse_submodules(sub.ptr, C.git_submodule_recurse_t(recurse)) + 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() }