From efd61a4bc0443ae604dbb4dbebd3a123c079b65b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Fri, 31 Jul 2015 11:37:18 +0200 Subject: [PATCH] Wrap MergeBases While here, test MergeBase as well. --- merge.go | 31 +++++++++++++++++++++++++++ merge_test.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/merge.go b/merge.go index 5b68a8b..8c87391 100644 --- a/merge.go +++ b/merge.go @@ -10,6 +10,7 @@ extern git_annotated_commit* _go_git_annotated_commit_array_get(git_annotated_co */ import "C" import ( + "reflect" "runtime" "unsafe" ) @@ -243,6 +244,36 @@ func (r *Repository) MergeBase(one *Oid, two *Oid) (*Oid, error) { return newOidFromC(&oid), nil } +// MergeBases retrieves the list of merge bases between two commits. +// +// If none are found, an empty slice is returned and the error is set +// approprately +func (r *Repository) MergeBases(one, two *Oid) ([]*Oid, error) { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + var coids C.git_oidarray + ret := C.git_merge_bases(&coids, r.ptr, one.toC(), two.toC()) + if ret < 0 { + return make([]*Oid, 0), MakeGitError(ret) + } + + oids := make([]*Oid, coids.count) + hdr := reflect.SliceHeader { + Data: uintptr(unsafe.Pointer(coids.ids)), + Len: int(coids.count), + Cap: int(coids.count), + } + + goSlice := *(*[]C.git_oid)(unsafe.Pointer(&hdr)) + + for i, cid := range goSlice { + oids[i] = newOidFromC(&cid) + } + + return oids, nil +} + //TODO: int git_merge_base_many(git_oid *out, git_repository *repo, size_t length, const git_oid input_array[]); //TODO: GIT_EXTERN(int) git_merge_base_octopus(git_oid *out,git_repository *repo,size_t length,const git_oid input_array[]); diff --git a/merge_test.go b/merge_test.go index 0b1faca..c09deed 100644 --- a/merge_test.go +++ b/merge_test.go @@ -2,6 +2,7 @@ package git import ( "testing" + "time" ) func TestMergeWithSelf(t *testing.T) { @@ -88,6 +89,64 @@ func TestMergeTreesWithoutAncestor(t *testing.T) { } +func appendCommit(t *testing.T, repo *Repository) (*Oid, *Oid) { + 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) + treeId, err := idx.WriteTree() + checkFatal(t, err) + + message := "This is another commit\n" + tree, err := repo.LookupTree(treeId) + checkFatal(t, err) + + ref, err := repo.LookupReference("HEAD") + checkFatal(t, err) + + parent, err := ref.Peel(ObjectCommit) + checkFatal(t, err) + + commitId, err := repo.CreateCommit("HEAD", sig, sig, message, tree, parent.(*Commit)) + checkFatal(t, err) + + return commitId, treeId +} + +func TestMergeBase(t *testing.T) { + repo := createTestRepo(t) + defer cleanupTestRepo(t, repo) + + commitAId, _ := seedTestRepo(t, repo) + commitBId, _ := appendCommit(t, repo) + + mergeBase, err := repo.MergeBase(commitAId, commitBId) + checkFatal(t, err) + + if mergeBase.Cmp(commitAId) != 0 { + t.Fatalf("unexpected merge base") + } + + mergeBases, err := repo.MergeBases(commitAId, commitBId) + checkFatal(t, err) + + if len(mergeBases) != 1 { + t.Fatalf("expected merge bases len to be 1, got %v", len(mergeBases)) + } + + if mergeBases[0].Cmp(commitAId) != 0 { + t.Fatalf("unexpected merge base") + } +} + func compareBytes(t *testing.T, expected, actual []byte) { for i, v := range expected { if actual[i] != v {