update to new merge API

This commit is contained in:
Jesse Ezell 2014-03-26 11:28:48 -07:00
parent 85420f2002
commit 50a3c4aa09
4 changed files with 73 additions and 111 deletions

View File

@ -5,8 +5,8 @@ package git
*/ */
import "C" import "C"
import ( import (
"runtime"
"os" "os"
"runtime"
) )
type CheckoutStrategy uint type CheckoutStrategy uint
@ -38,6 +38,15 @@ type CheckoutOpts struct {
FileOpenFlags int // Default is O_CREAT | O_TRUNC | O_WRONLY 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 // Convert the CheckoutOpts struct to the corresponding
// C-struct. Returns a pointer to ptr, or nil if opts is nil, in order // C-struct. Returns a pointer to ptr, or nil if opts is nil, in order
// to help with what to pass. // to help with what to pass.

137
merge.go
View File

@ -69,66 +69,47 @@ func (r *Repository) MergeHeadFromRef(ref *Reference) (*MergeHead, error) {
return mh, nil return mh, nil
} }
type MergeFlag int type MergeTreeFlag int
const ( const (
MergeFlagDefault MergeFlag = C.GIT_MERGE_DEFAULT MergeTreeFindRenames MergeTreeFlag = C.GIT_MERGE_TREE_FIND_RENAMES
MergeNoFastForward = C.GIT_MERGE_NO_FASTFORWARD
MergeFastForwardOnly = C.GIT_MERGE_FASTFORWARD_ONLY
) )
type MergeOptions struct { type MergeOptions struct {
Version uint
Flags MergeFlag
TreeOptions MergeTreeOptions
//TODO: CheckoutOptions CheckoutOptions
}
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(),
}
}
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 Version uint
Flags MergeTreeFlag Flags MergeTreeFlag
RenameThreshold uint RenameThreshold uint
TargetLimit uint TargetLimit uint
//TODO: SimilarityMetric *DiffSimilarityMetric
FileFavor MergeFileFavorType FileFavor MergeFileFavorType
//TODO: Diff similarity metric
} }
func DefaultMergeTreeOptions() MergeTreeOptions { func mergeOptionsFromC(opts *C.git_merge_options) MergeOptions {
return MergeTreeOptions{Version: 1} 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),
}
} }
func (mo *MergeTreeOptions) toC() *C.git_merge_tree_opts { func DefaultMergeOptions() (MergeOptions, error) {
return &C.git_merge_tree_opts{ 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 (mo *MergeOptions) toC() *C.git_merge_options {
if mo == nil {
return nil
}
return &C.git_merge_options{
version: C.uint(mo.Version), version: C.uint(mo.Version),
flags: C.git_merge_tree_flag_t(mo.Flags), flags: C.git_merge_tree_flag_t(mo.Flags),
rename_threshold: C.uint(mo.RenameThreshold), rename_threshold: C.uint(mo.RenameThreshold),
@ -137,69 +118,35 @@ func (mo *MergeTreeOptions) toC() *C.git_merge_tree_opts {
} }
} }
type MergeResult struct { type MergeFileFavorType int
ptr *C.git_merge_result
}
func newMergeResultFromC(c *C.git_merge_result) *MergeResult { const (
mr := &MergeResult{ptr: c} MergeFileFavorNormal MergeFileFavorType = C.GIT_MERGE_FILE_FAVOR_NORMAL
runtime.SetFinalizer(mr, (*MergeResult).Free) MergeFileFavorOurs = C.GIT_MERGE_FILE_FAVOR_OURS
return mr MergeFileFavorTheirs = C.GIT_MERGE_FILE_FAVOR_THEIRS
} MergeFileFavorUnion = C.GIT_MERGE_FILE_FAVOR_UNION
)
func (mr *MergeResult) Free() { func (r *Repository) Merge(theirHeads []*MergeHead, mergeOptions *MergeOptions, checkoutOptions *CheckoutOpts) error {
runtime.SetFinalizer(mr, nil)
C.git_merge_result_free(mr.ptr)
}
func (mr *MergeResult) IsFastForward() bool {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_merge_result_is_fastforward(mr.ptr) cMergeOpts := mergeOptions.toC()
return ret != 0 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)) gmerge_head_array := make([]*C.git_merge_head, len(theirHeads))
for i := 0; i < len(theirHeads); i++ { for i := 0; i < len(theirHeads); i++ {
gmerge_head_array[i] = theirHeads[i].ptr gmerge_head_array[i] = theirHeads[i].ptr
} }
ptr := unsafe.Pointer(&gmerge_head_array[0]) 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 { 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() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
@ -215,7 +162,7 @@ func (r *Repository) MergeCommits(ours *Commit, theirs *Commit, options MergeTre
return idx, nil 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() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()

View File

@ -4,7 +4,7 @@ import (
"testing" "testing"
) )
func Test_Merge_With_Self(t *testing.T) { func TestMergeWithSelf(t *testing.T) {
repo := createTestRepo(t) repo := createTestRepo(t)
seedTestRepo(t, repo) seedTestRepo(t, repo)
@ -15,13 +15,9 @@ func Test_Merge_With_Self(t *testing.T) {
mergeHead, err := repo.MergeHeadFromRef(master) mergeHead, err := repo.MergeHeadFromRef(master)
checkFatal(t, err) checkFatal(t, err)
options := DefaultMergeOptions() options, _ := DefaultMergeOptions()
mergeHeads := make([]*MergeHead, 1) mergeHeads := make([]*MergeHead, 1)
mergeHeads[0] = mergeHead mergeHeads[0] = mergeHead
results, err := repo.Merge(mergeHeads, options) err = repo.Merge(mergeHeads, &options, nil)
checkFatal(t, err) checkFatal(t, err)
if !results.IsUpToDate() {
t.Fatal("Expected up to date")
}
} }

View File

@ -287,22 +287,32 @@ func (sub *Submodule) Open() (*Repository, error) {
return repo, nil return repo, nil
} }
func (sub *Submodule) Reload() error { func (sub *Submodule) Reload(force bool) error {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() 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 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
return nil return nil
} }
func (repo *Repository) ReloadAllSubmodules() error { func (repo *Repository) ReloadAllSubmodules(force bool) error {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() 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 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }