Cherrypick
This commit is contained in:
parent
56ed0b22d7
commit
c78b4d665e
13
checkout.go
13
checkout.go
|
@ -40,6 +40,19 @@ type CheckoutOpts struct {
|
|||
TargetDirectory string // Alternative checkout path to workdir
|
||||
}
|
||||
|
||||
func checkoutOptionsFromC(c *C.git_checkout_options) CheckoutOpts {
|
||||
opts := CheckoutOpts{}
|
||||
opts.Strategy = CheckoutStrategy(c.checkout_strategy)
|
||||
opts.DisableFilters = c.disable_filters != 0
|
||||
opts.DirMode = os.FileMode(c.dir_mode)
|
||||
opts.FileMode = os.FileMode(c.file_mode)
|
||||
opts.FileOpenFlags = int(c.file_open_flags)
|
||||
if c.target_directory != nil {
|
||||
opts.TargetDirectory = C.GoString(c.target_directory)
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func (opts *CheckoutOpts) toC() *C.git_checkout_options {
|
||||
if opts == nil {
|
||||
return nil
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
package git
|
||||
|
||||
/*
|
||||
#include <git2.h>
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type CherrypickOptions struct {
|
||||
Version uint
|
||||
Mainline uint
|
||||
MergeOpts MergeOptions
|
||||
CheckoutOpts CheckoutOpts
|
||||
}
|
||||
|
||||
func cherrypickOptionsFromC(c *C.git_cherrypick_options) CherrypickOptions {
|
||||
opts := CherrypickOptions{
|
||||
Version: uint(c.version),
|
||||
Mainline: uint(c.mainline),
|
||||
MergeOpts: mergeOptionsFromC(&c.merge_opts),
|
||||
CheckoutOpts: checkoutOptionsFromC(&c.checkout_opts),
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func (opts *CherrypickOptions) toC() *C.git_cherrypick_options {
|
||||
if opts == nil {
|
||||
return nil
|
||||
}
|
||||
c := C.git_cherrypick_options{}
|
||||
c.version = C.uint(opts.Version)
|
||||
c.mainline = C.uint(opts.Mainline)
|
||||
c.merge_opts = *opts.MergeOpts.toC()
|
||||
c.checkout_opts = *opts.CheckoutOpts.toC()
|
||||
return &c
|
||||
}
|
||||
|
||||
func freeCherrypickOpts(ptr *C.git_cherrypick_options) {
|
||||
if ptr == nil {
|
||||
return
|
||||
}
|
||||
freeCheckoutOpts(&ptr.checkout_opts)
|
||||
}
|
||||
|
||||
func DefaultCherrypickOptions() (CherrypickOptions, error) {
|
||||
c := C.git_cherrypick_options{}
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
ecode := C.git_cherrypick_init_options(&c, C.GIT_CHERRYPICK_OPTIONS_VERSION)
|
||||
if ecode < 0 {
|
||||
return CherrypickOptions{}, MakeGitError(ecode)
|
||||
}
|
||||
defer freeCherrypickOpts(&c)
|
||||
return cherrypickOptionsFromC(&c), nil
|
||||
}
|
||||
|
||||
func (v *Repository) Cherrypick(commit *Commit, opts CherrypickOptions) error {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
cOpts := opts.toC()
|
||||
defer freeCherrypickOpts(cOpts)
|
||||
|
||||
ecode := C.git_cherrypick(v.ptr, commit.cast_ptr, cOpts)
|
||||
if ecode < 0 {
|
||||
return MakeGitError(ecode)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func checkout(t *testing.T, repo *Repository, commit *Commit) {
|
||||
tree, err := commit.Tree()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = repo.CheckoutTree(tree, &CheckoutOpts{Strategy: CheckoutSafe})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = repo.SetHeadDetached(commit.Id(), commit.Author(), "checkout")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
const content = "Herro, Worrd!"
|
||||
|
||||
func readReadme(t *testing.T, repo *Repository) string {
|
||||
bytes, err := ioutil.ReadFile(pathInRepo(repo, "README"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
func TestCherrypick(t *testing.T) {
|
||||
repo := createTestRepo(t)
|
||||
c1, _ := seedTestRepo(t, repo)
|
||||
c2, _ := updateReadme(t, repo, content)
|
||||
|
||||
commit1, err := repo.LookupCommit(c1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
commit2, err := repo.LookupCommit(c2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
checkout(t, repo, commit1)
|
||||
|
||||
if readReadme(t, repo) == content {
|
||||
t.Fatalf("README has wrong content after checking out initial commit")
|
||||
}
|
||||
|
||||
opts, err := DefaultCherrypickOptions()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = repo.Cherrypick(commit2, opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if readReadme(t, repo) != content {
|
||||
t.Fatalf("README has wrong contents after cherry-picking")
|
||||
}
|
||||
|
||||
state := repo.State()
|
||||
if state != RepositoryStateCherrypick {
|
||||
t.Fatal("Incorrect repository state: ", state)
|
||||
}
|
||||
}
|
|
@ -57,6 +57,10 @@ func seedTestRepo(t *testing.T, repo *Repository) (*Oid, *Oid) {
|
|||
return commitId, treeId
|
||||
}
|
||||
|
||||
func pathInRepo(repo *Repository, name string) string {
|
||||
return path.Join(path.Dir(path.Dir(repo.Path())), name)
|
||||
}
|
||||
|
||||
func updateReadme(t *testing.T, repo *Repository, content string) (*Oid, *Oid) {
|
||||
loc, err := time.LoadLocation("Europe/Berlin")
|
||||
checkFatal(t, err)
|
||||
|
@ -67,7 +71,7 @@ func updateReadme(t *testing.T, repo *Repository, content string) (*Oid, *Oid) {
|
|||
}
|
||||
|
||||
tmpfile := "README"
|
||||
err = ioutil.WriteFile(path.Join(path.Dir(path.Dir(repo.Path())), tmpfile), []byte(content), 0644)
|
||||
err = ioutil.WriteFile(pathInRepo(repo, tmpfile), []byte(content), 0644)
|
||||
checkFatal(t, err)
|
||||
|
||||
idx, err := repo.Index()
|
||||
|
|
Loading…
Reference in New Issue