From a1f25eafec55509d49dffb4c84f7c5b729e6a85e Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 16 Feb 2016 21:34:43 -0800 Subject: handles, merge: simplify code, don't copy file contents --- merge.go | 65 +++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 31 insertions(+), 34 deletions(-) (limited to 'merge.go') diff --git a/merge.go b/merge.go index 535a5e7..06f5676 100644 --- a/merge.go +++ b/merge.go @@ -6,6 +6,7 @@ package git extern git_annotated_commit** _go_git_make_merge_head_array(size_t len); extern void _go_git_annotated_commit_array_set(git_annotated_commit** array, git_annotated_commit* ptr, size_t n); extern git_annotated_commit* _go_git_annotated_commit_array_get(git_annotated_commit** array, size_t n); +extern int _go_git_merge_file(git_merge_file_result*, char*, size_t, char*, unsigned int, char*, size_t, char*, unsigned int, char*, size_t, char*, unsigned int, git_merge_file_options*); */ import "C" @@ -85,8 +86,8 @@ const ( ) type MergeOptions struct { - Version uint - TreeFlags MergeTreeFlag + Version uint + TreeFlags MergeTreeFlag RenameThreshold uint TargetLimit uint @@ -98,7 +99,7 @@ type MergeOptions struct { func mergeOptionsFromC(opts *C.git_merge_options) MergeOptions { return MergeOptions{ Version: uint(opts.version), - TreeFlags: MergeTreeFlag(opts.tree_flags), + TreeFlags: MergeTreeFlag(opts.tree_flags), RenameThreshold: uint(opts.rename_threshold), TargetLimit: uint(opts.target_limit), FileFavor: MergeFileFavor(opts.file_favor), @@ -262,10 +263,10 @@ func (r *Repository) MergeBases(one, two *Oid) ([]*Oid, error) { } oids := make([]*Oid, coids.count) - hdr := reflect.SliceHeader{ + hdr := reflect.SliceHeader { Data: uintptr(unsafe.Pointer(coids.ids)), - Len: int(coids.count), - Cap: int(coids.count), + Len: int(coids.count), + Cap: int(coids.count), } goSlice := *(*[]C.git_oid)(unsafe.Pointer(&hdr)) @@ -320,24 +321,6 @@ type MergeFileInput struct { Contents []byte } -// populate a C struct with merge file input, make sure to use freeMergeFileInput to clean up allocs -func populateCMergeFileInput(c *C.git_merge_file_input, input MergeFileInput) *C.char { - c.path = C.CString(input.Path) - var toFree *C.char - if input.Contents != nil { - toFree = C.CString(string(input.Contents)) - c.ptr = toFree - c.size = C.size_t(len(input.Contents)) - } - c.mode = C.uint(input.Mode) - return toFree -} - -func freeCMergeFileInput(c *C.git_merge_file_input, toFree *C.char) { - C.free(unsafe.Pointer(c.path)) - C.free(unsafe.Pointer(toFree)) -} - type MergeFileFlags int const ( @@ -382,16 +365,26 @@ func freeCMergeFileOptions(c *C.git_merge_file_options) { func MergeFile(ancestor MergeFileInput, ours MergeFileInput, theirs MergeFileInput, options *MergeFileOptions) (*MergeFileResult, error) { - var cancestor C.git_merge_file_input - var cours C.git_merge_file_input - var ctheirs C.git_merge_file_input + ancestorPath := C.CString(ancestor.Path) + defer C.free(unsafe.Pointer(ancestorPath)) + var ancestorContents *byte + if len(ancestor.Contents) > 0 { + ancestorContents = &ancestor.Contents[0] + } + + oursPath := C.CString(ours.Path) + defer C.free(unsafe.Pointer(oursPath)) + var oursContents *byte + if len(ours.Contents) > 0 { + oursContents = &ours.Contents[0] + } - t := populateCMergeFileInput(&cancestor, ancestor) - defer freeCMergeFileInput(&cancestor, t) - t = populateCMergeFileInput(&cours, ours) - defer freeCMergeFileInput(&cours, t) - t = populateCMergeFileInput(&ctheirs, theirs) - defer freeCMergeFileInput(&ctheirs, t) + theirsPath := C.CString(theirs.Path) + defer C.free(unsafe.Pointer(theirsPath)) + var theirsContents *byte + if len(theirs.Contents) > 0 { + theirsContents = &theirs.Contents[0] + } var copts *C.git_merge_file_options if options != nil { @@ -408,7 +401,11 @@ func MergeFile(ancestor MergeFileInput, ours MergeFileInput, theirs MergeFileInp defer runtime.UnlockOSThread() var result C.git_merge_file_result - ecode := C.git_merge_file(&result, &cancestor, &cours, &ctheirs, copts) + ecode := C._go_git_merge_file(&result, + (*C.char)(unsafe.Pointer(ancestorContents)), C.size_t(len(ancestor.Contents)), ancestorPath, C.uint(ancestor.Mode), + (*C.char)(unsafe.Pointer(oursContents)), C.size_t(len(ours.Contents)), oursPath, C.uint(ours.Mode), + (*C.char)(unsafe.Pointer(theirsContents)), C.size_t(len(theirs.Contents)), theirsPath, C.uint(theirs.Mode), + copts) if ecode < 0 { return nil, MakeGitError(ecode) } -- cgit v1.2.3