@@ -333,7 +333,7 @@ func (r *Repository) MergeBases(one, two *Oid) ([]*Oid, error) {
333333 runtime .KeepAlive (one )
334334 runtime .KeepAlive (two )
335335 if ret < 0 {
336- return make ([] * Oid , 0 ) , MakeGitError (ret )
336+ return nil , MakeGitError (ret )
337337 }
338338
339339 oids := make ([]* Oid , coids .count )
@@ -352,8 +352,78 @@ func (r *Repository) MergeBases(one, two *Oid) ([]*Oid, error) {
352352 return oids , nil
353353}
354354
355- //TODO: int git_merge_base_many(git_oid *out, git_repository *repo, size_t length, const git_oid input_array[]);
356- //TODO: GIT_EXTERN(int) git_merge_base_octopus(git_oid *out,git_repository *repo,size_t length,const git_oid input_array[]);
355+ // MergeBaseMany finds a merge base given a list of commits.
356+ func (r * Repository ) MergeBaseMany (oids []* Oid ) (* Oid , error ) {
357+ coids := make ([]C.git_oid , len (oids ))
358+ for i := 0 ; i < len (oids ); i ++ {
359+ coids [i ] = * oids [i ].toC ()
360+ }
361+
362+ runtime .LockOSThread ()
363+ defer runtime .UnlockOSThread ()
364+
365+ var oid C.git_oid
366+ ret := C .git_merge_base_many (& oid , r .ptr , C .size_t (len (oids )), & coids [0 ])
367+ runtime .KeepAlive (r )
368+ runtime .KeepAlive (coids )
369+ if ret < 0 {
370+ return nil , MakeGitError (ret )
371+ }
372+ return newOidFromC (& oid ), nil
373+ }
374+
375+ // MergeBasesMany finds all merge bases given a list of commits.
376+ func (r * Repository ) MergeBasesMany (oids []* Oid ) ([]* Oid , error ) {
377+ inCoids := make ([]C.git_oid , len (oids ))
378+ for i := 0 ; i < len (oids ); i ++ {
379+ inCoids [i ] = * oids [i ].toC ()
380+ }
381+
382+ runtime .LockOSThread ()
383+ defer runtime .UnlockOSThread ()
384+
385+ var outCoids C.git_oidarray
386+ ret := C .git_merge_bases_many (& outCoids , r .ptr , C .size_t (len (oids )), & inCoids [0 ])
387+ runtime .KeepAlive (r )
388+ runtime .KeepAlive (inCoids )
389+ if ret < 0 {
390+ return nil , MakeGitError (ret )
391+ }
392+
393+ outOids := make ([]* Oid , outCoids .count )
394+ hdr := reflect.SliceHeader {
395+ Data : uintptr (unsafe .Pointer (outCoids .ids )),
396+ Len : int (outCoids .count ),
397+ Cap : int (outCoids .count ),
398+ }
399+ goSlice := * (* []C.git_oid )(unsafe .Pointer (& hdr ))
400+
401+ for i , cid := range goSlice {
402+ outOids [i ] = newOidFromC (& cid )
403+ }
404+
405+ return outOids , nil
406+ }
407+
408+ // MergeBaseOctopus finds a merge base in preparation for an octopus merge.
409+ func (r * Repository ) MergeBaseOctopus (oids []* Oid ) (* Oid , error ) {
410+ coids := make ([]C.git_oid , len (oids ))
411+ for i := 0 ; i < len (oids ); i ++ {
412+ coids [i ] = * oids [i ].toC ()
413+ }
414+
415+ runtime .LockOSThread ()
416+ defer runtime .UnlockOSThread ()
417+
418+ var oid C.git_oid
419+ ret := C .git_merge_base_octopus (& oid , r .ptr , C .size_t (len (oids )), & coids [0 ])
420+ runtime .KeepAlive (r )
421+ runtime .KeepAlive (coids )
422+ if ret < 0 {
423+ return nil , MakeGitError (ret )
424+ }
425+ return newOidFromC (& oid ), nil
426+ }
357427
358428type MergeFileResult struct {
359429 Automergeable bool
0 commit comments