From 50a3c4aa0935adb798bc4ecf6612710908d227cf Mon Sep 17 00:00:00 2001 From: Jesse Ezell Date: Wed, 26 Mar 2014 11:28:48 -0700 Subject: [PATCH] update to new merge API --- checkout.go | 19 +++++-- merge.go | 137 ++++++++++++++++---------------------------------- merge_test.go | 10 ++-- submodule.go | 18 +++++-- 4 files changed, 73 insertions(+), 111 deletions(-) diff --git a/checkout.go b/checkout.go index 5b72b9a..456c302 100644 --- a/checkout.go +++ b/checkout.go @@ -5,8 +5,8 @@ package git */ import "C" import ( - "runtime" "os" + "runtime" ) type CheckoutStrategy uint @@ -32,10 +32,19 @@ const ( type CheckoutOpts struct { Strategy CheckoutStrategy // Default will be a dry run - DisableFilters bool // Don't apply filters like CRLF conversion - DirMode os.FileMode // Default is 0755 - FileMode os.FileMode // Default is 0644 or 0755 as dictated by blob - FileOpenFlags int // Default is O_CREAT | O_TRUNC | O_WRONLY + DisableFilters bool // Don't apply filters like CRLF conversion + DirMode os.FileMode // Default is 0755 + FileMode os.FileMode // Default is 0644 or 0755 as dictated by blob + FileOpenFlags int // Default is O_CREAT | O_TRUNC | O_WRONLY +} + +func (opts *CheckoutOpts) toC() *C.git_checkout_options { + if opts == nil { + return nil + } + c := C.git_checkout_options{} + populateCheckoutOpts(&c, opts) + return &c } // Convert the CheckoutOpts struct to the corresponding diff --git a/merge.go b/merge.go index d5f5cb9..d8a8936 100644 --- a/merge.go +++ b/merge.go @@ -69,66 +69,47 @@ func (r *Repository) MergeHeadFromRef(ref *Reference) (*MergeHead, error) { return mh, nil } -type MergeFlag int +type MergeTreeFlag int const ( - MergeFlagDefault MergeFlag = C.GIT_MERGE_DEFAULT - MergeNoFastForward = C.GIT_MERGE_NO_FASTFORWARD - MergeFastForwardOnly = C.GIT_MERGE_FASTFORWARD_ONLY + MergeTreeFindRenames MergeTreeFlag = C.GIT_MERGE_TREE_FIND_RENAMES ) type MergeOptions struct { Version uint - Flags MergeFlag + Flags MergeTreeFlag - TreeOptions MergeTreeOptions - //TODO: CheckoutOptions CheckoutOptions + RenameThreshold uint + TargetLimit uint + FileFavor MergeFileFavorType + + //TODO: Diff similarity metric } -func DefaultMergeOptions() MergeOptions { - options := MergeOptions{Version: 1} - options.TreeOptions = DefaultMergeTreeOptions() - return options -} - -func (mo *MergeOptions) toC() *C.git_merge_opts { - return &C.git_merge_opts{ - version: C.uint(mo.Version), - merge_flags: C.git_merge_flags_t(mo.Flags), - merge_tree_opts: *mo.TreeOptions.toC(), +func mergeOptionsFromC(opts *C.git_merge_options) MergeOptions { + return MergeOptions{ + Version: uint(opts.version), + Flags: MergeTreeFlag(opts.flags), + RenameThreshold: uint(opts.rename_threshold), + TargetLimit: uint(opts.target_limit), + FileFavor: MergeFileFavorType(opts.file_favor), } } -type MergeTreeFlag int - -const ( - MergeTreeFindRenames MergeTreeFlag = 1 << 0 -) - -type MergeFileFavorType int - -const ( - MergeFileFavorNormal MergeFileFavorType = 0 - MergeFileFavorOurs = 1 - MergeFileFavorTheirs = 2 - MergeFileFavorUnion = 3 -) - -type MergeTreeOptions struct { - Version uint - Flags MergeTreeFlag - RenameThreshold uint - TargetLimit uint - //TODO: SimilarityMetric *DiffSimilarityMetric - FileFavor MergeFileFavorType +func DefaultMergeOptions() (MergeOptions, error) { + opts := C.git_merge_options{} + ecode := C.git_merge_init_options(&opts, C.GIT_MERGE_OPTIONS_VERSION) + if ecode < 0 { + return MergeOptions{}, MakeGitError(ecode) + } + return mergeOptionsFromC(&opts), nil } -func DefaultMergeTreeOptions() MergeTreeOptions { - return MergeTreeOptions{Version: 1} -} - -func (mo *MergeTreeOptions) toC() *C.git_merge_tree_opts { - return &C.git_merge_tree_opts{ +func (mo *MergeOptions) toC() *C.git_merge_options { + if mo == nil { + return nil + } + return &C.git_merge_options{ version: C.uint(mo.Version), flags: C.git_merge_tree_flag_t(mo.Flags), rename_threshold: C.uint(mo.RenameThreshold), @@ -137,69 +118,35 @@ func (mo *MergeTreeOptions) toC() *C.git_merge_tree_opts { } } -type MergeResult struct { - ptr *C.git_merge_result -} +type MergeFileFavorType int -func newMergeResultFromC(c *C.git_merge_result) *MergeResult { - mr := &MergeResult{ptr: c} - runtime.SetFinalizer(mr, (*MergeResult).Free) - return mr -} +const ( + MergeFileFavorNormal MergeFileFavorType = C.GIT_MERGE_FILE_FAVOR_NORMAL + MergeFileFavorOurs = C.GIT_MERGE_FILE_FAVOR_OURS + MergeFileFavorTheirs = C.GIT_MERGE_FILE_FAVOR_THEIRS + MergeFileFavorUnion = C.GIT_MERGE_FILE_FAVOR_UNION +) -func (mr *MergeResult) Free() { - runtime.SetFinalizer(mr, nil) - C.git_merge_result_free(mr.ptr) -} - -func (mr *MergeResult) IsFastForward() bool { +func (r *Repository) Merge(theirHeads []*MergeHead, mergeOptions *MergeOptions, checkoutOptions *CheckoutOpts) error { runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_merge_result_is_fastforward(mr.ptr) - return ret != 0 -} + cMergeOpts := mergeOptions.toC() + cCheckoutOpts := checkoutOptions.toC() -func (mr *MergeResult) IsUpToDate() bool { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - ret := C.git_merge_result_is_uptodate(mr.ptr) - return ret != 0 -} - -func (mr *MergeResult) FastForwardId() (*Oid, error) { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - var oid C.git_oid - ret := C.git_merge_result_fastforward_id(&oid, mr.ptr) - if ret < 0 { - return nil, MakeGitError(ret) - } - return newOidFromC(&oid), nil -} - -func (r *Repository) Merge(theirHeads []*MergeHead, options MergeOptions) (*MergeResult, error) { - runtime.LockOSThread() - defer runtime.UnlockOSThread() - - var result *C.git_merge_result - - copts := options.toC() gmerge_head_array := make([]*C.git_merge_head, len(theirHeads)) for i := 0; i < len(theirHeads); i++ { gmerge_head_array[i] = theirHeads[i].ptr } ptr := unsafe.Pointer(&gmerge_head_array[0]) - err := C.git_merge(&result, r.ptr, (**C.git_merge_head)(ptr), C.size_t(len(theirHeads)), copts) + err := C.git_merge(r.ptr, (**C.git_merge_head)(ptr), C.size_t(len(theirHeads)), cMergeOpts, cCheckoutOpts) if err < 0 { - return nil, MakeGitError(err) + return MakeGitError(err) } - return newMergeResultFromC(result), nil + return nil } -func (r *Repository) MergeCommits(ours *Commit, theirs *Commit, options MergeTreeOptions) (*Index, error) { +func (r *Repository) MergeCommits(ours *Commit, theirs *Commit, options MergeOptions) (*Index, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() @@ -215,7 +162,7 @@ func (r *Repository) MergeCommits(ours *Commit, theirs *Commit, options MergeTre return idx, nil } -func (r *Repository) MergeTrees(ancestor *Tree, ours *Tree, theirs *Tree, options MergeTreeOptions) (*Index, error) { +func (r *Repository) MergeTrees(ancestor *Tree, ours *Tree, theirs *Tree, options MergeOptions) (*Index, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() diff --git a/merge_test.go b/merge_test.go index 9bf9b9d..74f08bc 100644 --- a/merge_test.go +++ b/merge_test.go @@ -4,7 +4,7 @@ import ( "testing" ) -func Test_Merge_With_Self(t *testing.T) { +func TestMergeWithSelf(t *testing.T) { repo := createTestRepo(t) seedTestRepo(t, repo) @@ -15,13 +15,9 @@ func Test_Merge_With_Self(t *testing.T) { mergeHead, err := repo.MergeHeadFromRef(master) checkFatal(t, err) - options := DefaultMergeOptions() + options, _ := DefaultMergeOptions() mergeHeads := make([]*MergeHead, 1) mergeHeads[0] = mergeHead - results, err := repo.Merge(mergeHeads, options) + err = repo.Merge(mergeHeads, &options, nil) checkFatal(t, err) - - if !results.IsUpToDate() { - t.Fatal("Expected up to date") - } } diff --git a/submodule.go b/submodule.go index a94afd4..e192e15 100644 --- a/submodule.go +++ b/submodule.go @@ -287,22 +287,32 @@ func (sub *Submodule) Open() (*Repository, error) { return repo, nil } -func (sub *Submodule) Reload() error { +func (sub *Submodule) Reload(force bool) error { runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_submodule_reload(sub.ptr) + cforce := C.int(0) + if force { + cforce = C.int(1) + } + + ret := C.git_submodule_reload(sub.ptr, cforce) if ret < 0 { return MakeGitError(ret) } return nil } -func (repo *Repository) ReloadAllSubmodules() error { +func (repo *Repository) ReloadAllSubmodules(force bool) error { runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_submodule_reload_all(repo.ptr) + cforce := C.int(0) + if force { + cforce = C.int(1) + } + + ret := C.git_submodule_reload_all(repo.ptr, cforce) if ret < 0 { return MakeGitError(ret) }