| 585 | } |
| 586 | |
| 587 | func (v *Repository) CreateCommitFromIds( |
| 588 | refname string, author, committer *Signature, |
| 589 | message string, tree *Oid, parents ...*Oid) (*Oid, error) { |
| 590 | |
| 591 | oid := new(Oid) |
| 592 | |
| 593 | var cref *C.char |
| 594 | if refname == "" { |
| 595 | cref = nil |
| 596 | } else { |
| 597 | cref = C.CString(refname) |
| 598 | defer C.free(unsafe.Pointer(cref)) |
| 599 | } |
| 600 | |
| 601 | cmsg := C.CString(message) |
| 602 | defer C.free(unsafe.Pointer(cmsg)) |
| 603 | |
| 604 | var parentsarg **C.git_oid = nil |
| 605 | |
| 606 | nparents := len(parents) |
| 607 | if nparents > 0 { |
| 608 | // All this awful pointer arithmetic is needed to avoid passing a Go |
| 609 | // pointer to Go pointer into C. Other methods (like CreateCommits) are |
| 610 | // fine without this workaround because they are just passing Go pointers |
| 611 | // to C pointers, but arrays-of-pointers-to-git_oid are a bit special since |
| 612 | // both the array and the objects are allocated from Go. |
| 613 | var emptyOidPtr *C.git_oid |
| 614 | sizeofOidPtr := unsafe.Sizeof(emptyOidPtr) |
| 615 | parentsarg = (**C.git_oid)(C.calloc(C.size_t(uintptr(nparents)), C.size_t(sizeofOidPtr))) |
| 616 | defer C.free(unsafe.Pointer(parentsarg)) |
| 617 | parentsptr := uintptr(unsafe.Pointer(parentsarg)) |
| 618 | for _, v := range parents { |
| 619 | *(**C.git_oid)(unsafe.Pointer(parentsptr)) = v.toC() |
| 620 | parentsptr += sizeofOidPtr |
| 621 | } |
| 622 | } |
| 623 | |
| 624 | authorSig, err := author.toC() |
| 625 | if err != nil { |
| 626 | return nil, err |
| 627 | } |
| 628 | defer C.git_signature_free(authorSig) |
| 629 | |
| 630 | committerSig, err := committer.toC() |
| 631 | if err != nil { |
| 632 | return nil, err |
| 633 | } |
| 634 | defer C.git_signature_free(committerSig) |
| 635 | |
| 636 | runtime.LockOSThread() |
| 637 | defer runtime.UnlockOSThread() |
| 638 | |
| 639 | ret := C.git_commit_create_from_ids( |
| 640 | oid.toC(), v.ptr, cref, |
| 641 | authorSig, committerSig, |
| 642 | nil, cmsg, tree.toC(), C.size_t(nparents), parentsarg) |
| 643 | |
| 644 | runtime.KeepAlive(v) |