diff options
| author | Carlos MartÃn Nieto <[email protected]> | 2019-01-08 09:30:36 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-01-08 09:30:36 +0000 |
| commit | 8766f9f36cfb30934b7133365aa3d1e91086bafa (patch) | |
| tree | 705e564b9dedf0ceced47e6f01012cb9fcb6322f /repository.go | |
| parent | 2609f4c6f25a7da56e2e4960c250ea3dfb53e82b (diff) | |
| parent | 6d67bde74a667dcdd060ef519832e8fd81064a8e (diff) | |
Merge pull request #466 from lhchavez/repository-create_commit_from_ids
Add support for CreateCommitFromIds
Diffstat (limited to 'repository.go')
| -rw-r--r-- | repository.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/repository.go b/repository.go index 74924b7..3e0d20f 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 ( @@ -389,6 +391,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) |
