Merge pull request #466 from lhchavez/repository-create_commit_from_ids
Add support for CreateCommitFromIds
(cherry picked from commit 8766f9f36c
)
This commit is contained in:
parent
9fd0d987ae
commit
c1c2b5a730
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestCreateCommitFromIds(t *testing.T) {
|
||||
t.Parallel()
|
||||
repo := createTestRepo(t)
|
||||
defer cleanupTestRepo(t, repo)
|
||||
|
||||
loc, err := time.LoadLocation("Europe/Berlin")
|
||||
checkFatal(t, err)
|
||||
sig := &Signature{
|
||||
Name: "Rand Om Hacker",
|
||||
Email: "random@hacker.com",
|
||||
When: time.Date(2013, 03, 06, 14, 30, 0, 0, loc),
|
||||
}
|
||||
|
||||
idx, err := repo.Index()
|
||||
checkFatal(t, err)
|
||||
err = idx.AddByPath("README")
|
||||
checkFatal(t, err)
|
||||
err = idx.Write()
|
||||
checkFatal(t, err)
|
||||
treeId, err := idx.WriteTree()
|
||||
checkFatal(t, err)
|
||||
|
||||
message := "This is a commit\n"
|
||||
tree, err := repo.LookupTree(treeId)
|
||||
checkFatal(t, err)
|
||||
expectedCommitId, err := repo.CreateCommit("HEAD", sig, sig, message, tree)
|
||||
checkFatal(t, err)
|
||||
|
||||
commitId, err := repo.CreateCommitFromIds("", sig, sig, message, treeId)
|
||||
checkFatal(t, err)
|
||||
|
||||
if !expectedCommitId.Equal(commitId) {
|
||||
t.Errorf("mismatched commit ids, expected %v, got %v", expectedCommitId.String(), commitId.String())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue