summaryrefslogtreecommitdiff
path: root/repository.go
diff options
context:
space:
mode:
Diffstat (limited to 'repository.go')
-rw-r--r--repository.go80
1 files changed, 77 insertions, 3 deletions
diff --git a/repository.go b/repository.go
index abf8b71..07b2605 100644
--- a/repository.go
+++ b/repository.go
@@ -3,6 +3,8 @@ package git
/*
#include <git2.h>
#include <git2/sys/repository.h>
+#include <git2/sys/commit.h>
+#include <string.h>
*/
import "C"
import (
@@ -19,10 +21,10 @@ type Repository struct {
Remotes RemoteCollection
// Submodules represents the collection of submodules and can
// be used to add, remove and configure submodules in this
- // repostiory.
+ // repository.
Submodules SubmoduleCollection
// References represents the collection of references and can
- // be used to create, remove or update refernces for this repository.
+ // be used to create, remove or update references for this repository.
References ReferenceCollection
// Notes represents the collection of notes and can be used to
// read, write and delete notes from this repository.
@@ -174,7 +176,7 @@ func (v *Repository) lookupType(id *Oid, t ObjectType) (*Object, error) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
- ret := C.git_object_lookup(&ptr, v.ptr, id.toC(), C.git_otype(t))
+ ret := C.git_object_lookup(&ptr, v.ptr, id.toC(), C.git_object_t(t))
runtime.KeepAlive(id)
if ret < 0 {
return nil, MakeGitError(ret)
@@ -192,6 +194,7 @@ func (v *Repository) LookupTree(id *Oid) (*Tree, error) {
if err != nil {
return nil, err
}
+ defer obj.Free()
return obj.AsTree()
}
@@ -201,6 +204,7 @@ func (v *Repository) LookupCommit(id *Oid) (*Commit, error) {
if err != nil {
return nil, err
}
+ defer obj.Free()
return obj.AsCommit()
}
@@ -210,6 +214,7 @@ func (v *Repository) LookupBlob(id *Oid) (*Blob, error) {
if err != nil {
return nil, err
}
+ defer obj.Free()
return obj.AsBlob()
}
@@ -219,6 +224,7 @@ func (v *Repository) LookupTag(id *Oid) (*Tag, error) {
if err != nil {
return nil, err
}
+ defer obj.Free()
return obj.AsTag()
}
@@ -389,6 +395,74 @@ func (v *Repository) CreateCommit(
return oid, nil
}
+func (v *Repository) CreateCommitFromIds(
+ refname string, author, committer *Signature,
+ message string, tree *Oid, parents ...*Oid) (*Oid, error) {
+
+ oid := new(Oid)
+
+ var cref *C.char
+ if refname == "" {
+ cref = nil
+ } else {
+ cref = C.CString(refname)
+ defer C.free(unsafe.Pointer(cref))
+ }
+
+ cmsg := C.CString(message)
+ defer C.free(unsafe.Pointer(cmsg))
+
+ var parentsarg **C.git_oid = nil
+
+ nparents := len(parents)
+ if nparents > 0 {
+ // All this awful pointer arithmetic is needed to avoid passing a Go
+ // pointer to Go pointer into C. Other methods (like CreateCommits) are
+ // fine without this workaround because they are just passing Go pointers
+ // to C pointers, but arrays-of-pointers-to-git_oid are a bit special since
+ // both the array and the objects are allocated from Go.
+ var emptyOidPtr *C.git_oid
+ sizeofOidPtr := unsafe.Sizeof(emptyOidPtr)
+ parentsarg = (**C.git_oid)(C.calloc(C.size_t(uintptr(nparents)), C.size_t(sizeofOidPtr)))
+ defer C.free(unsafe.Pointer(parentsarg))
+ parentsptr := uintptr(unsafe.Pointer(parentsarg))
+ for _, v := range parents {
+ *(**C.git_oid)(unsafe.Pointer(parentsptr)) = v.toC()
+ parentsptr += sizeofOidPtr
+ }
+ }
+
+ authorSig, err := author.toC()
+ if err != nil {
+ return nil, err
+ }
+ defer C.git_signature_free(authorSig)
+
+ committerSig, err := committer.toC()
+ if err != nil {
+ return nil, err
+ }
+ defer C.git_signature_free(committerSig)
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_commit_create_from_ids(
+ oid.toC(), v.ptr, cref,
+ authorSig, committerSig,
+ nil, cmsg, tree.toC(), C.size_t(nparents), parentsarg)
+
+ runtime.KeepAlive(v)
+ runtime.KeepAlive(oid)
+ runtime.KeepAlive(tree)
+ runtime.KeepAlive(parents)
+ if ret < 0 {
+ return nil, MakeGitError(ret)
+ }
+
+ return oid, nil
+}
+
func (v *Odb) Free() {
runtime.SetFinalizer(v, nil)
C.git_odb_free(v.ptr)