update to new merge API
This commit is contained in:
parent
85420f2002
commit
50a3c4aa09
19
checkout.go
19
checkout.go
|
@ -5,8 +5,8 @@ package git
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"runtime"
|
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CheckoutStrategy uint
|
type CheckoutStrategy uint
|
||||||
|
@ -32,10 +32,19 @@ const (
|
||||||
|
|
||||||
type CheckoutOpts struct {
|
type CheckoutOpts struct {
|
||||||
Strategy CheckoutStrategy // Default will be a dry run
|
Strategy CheckoutStrategy // Default will be a dry run
|
||||||
DisableFilters bool // Don't apply filters like CRLF conversion
|
DisableFilters bool // Don't apply filters like CRLF conversion
|
||||||
DirMode os.FileMode // Default is 0755
|
DirMode os.FileMode // Default is 0755
|
||||||
FileMode os.FileMode // Default is 0644 or 0755 as dictated by blob
|
FileMode os.FileMode // Default is 0644 or 0755 as dictated by blob
|
||||||
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
|
||||||
|
|
137
merge.go
137
merge.go
|
@ -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
|
Version uint
|
||||||
Flags MergeFlag
|
Flags MergeTreeFlag
|
||||||
|
|
||||||
TreeOptions MergeTreeOptions
|
RenameThreshold uint
|
||||||
//TODO: CheckoutOptions CheckoutOptions
|
TargetLimit uint
|
||||||
|
FileFavor MergeFileFavorType
|
||||||
|
|
||||||
|
//TODO: Diff similarity metric
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultMergeOptions() MergeOptions {
|
func mergeOptionsFromC(opts *C.git_merge_options) MergeOptions {
|
||||||
options := MergeOptions{Version: 1}
|
return MergeOptions{
|
||||||
options.TreeOptions = DefaultMergeTreeOptions()
|
Version: uint(opts.version),
|
||||||
return options
|
Flags: MergeTreeFlag(opts.flags),
|
||||||
}
|
RenameThreshold: uint(opts.rename_threshold),
|
||||||
|
TargetLimit: uint(opts.target_limit),
|
||||||
func (mo *MergeOptions) toC() *C.git_merge_opts {
|
FileFavor: MergeFileFavorType(opts.file_favor),
|
||||||
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
|
func DefaultMergeOptions() (MergeOptions, error) {
|
||||||
|
opts := C.git_merge_options{}
|
||||||
const (
|
ecode := C.git_merge_init_options(&opts, C.GIT_MERGE_OPTIONS_VERSION)
|
||||||
MergeTreeFindRenames MergeTreeFlag = 1 << 0
|
if ecode < 0 {
|
||||||
)
|
return MergeOptions{}, MakeGitError(ecode)
|
||||||
|
}
|
||||||
type MergeFileFavorType int
|
return mergeOptionsFromC(&opts), nil
|
||||||
|
|
||||||
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 DefaultMergeTreeOptions() MergeTreeOptions {
|
func (mo *MergeOptions) toC() *C.git_merge_options {
|
||||||
return MergeTreeOptions{Version: 1}
|
if mo == nil {
|
||||||
}
|
return nil
|
||||||
|
}
|
||||||
func (mo *MergeTreeOptions) toC() *C.git_merge_tree_opts {
|
return &C.git_merge_options{
|
||||||
return &C.git_merge_tree_opts{
|
|
||||||
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()
|
||||||
|
|
||||||
|
|
|
@ -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")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
18
submodule.go
18
submodule.go
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue