Repository: libgit2/git2go (go)

Issue:
Support git_remote_create_with_opts
Hello, first of all, thanks for such a great project!

It would be nice to support  https://libgit2.org/libgit2/#HEAD/group/remote/git_remote_create_with_opts , which is introduced in v0.28.0 . Thank you!




Pull request description:
Support git_remote_create_with_opts (#733)
Closes #645

(cherry picked from commit 73d97b9bbe7c9a7747af20aad670baba33b5e390)

Patch:
diff --git a/remote.go b/remote.go
index e40a316..8ad5509 100644
--- a/remote.go
+++ b/remote.go
@@ -18,6 +18,23 @@ import (
 	"unsafe"
 )
 
+// RemoteCreateOptionsFlag is Remote creation options flags
+type RemoteCreateOptionsFlag uint
+
+const (
+	// Ignore the repository apply.insteadOf configuration
+	RemoteCreateSkipInsteadof RemoteCreateOptionsFlag = C.GIT_REMOTE_CREATE_SKIP_INSTEADOF
+	// Don't build a fetchspec from the name if none is set
+	RemoteCreateSkipDefaultFetchspec RemoteCreateOptionsFlag = C.GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC
+)
+
+// RemoteCreateOptions contains options for creating a remote
+type RemoteCreateOptions struct {
+	Name       string
+	FetchSpec  string
+	Flags      RemoteCreateOptionsFlag
+}
+
 type TransferProgress struct {
 	TotalObjects    uint
 	IndexedObjects  uint
@@ -539,6 +556,28 @@ func (c *RemoteCollection) Create(name string, url string) (*Remote, error) {
 	return remote, nil
 }
 
+//CreateWithOptions Creates a repository object with extended options.
+func (c *RemoteCollection) CreateWithOptions(url string, option *RemoteCreateOptions) (*Remote, error) {
+	remote := &Remote{repo: c.repo}
+
+	curl := C.CString(url)
+	defer C.free(unsafe.Pointer(curl))
+
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+
+	copts := populateRemoteCreateOptions(&C.git_remote_create_options{}, option, c.repo)
+	defer freeRemoteCreateOptions(copts)
+	ret := C.git_remote_create_with_opts(&remote.ptr, curl, copts)
+	runtime.KeepAlive(c.repo)
+	if ret < 0 {
+		return nil, MakeGitError(ret)
+	}
+
+	runtime.SetFinalizer(remote, (*Remote).Free)
+	return remote, nil
+}
+
 func (c *RemoteCollection) Delete(name string) error {
 	cname := C.CString(name)
 	defer C.free(unsafe.Pointer(cname))
@@ -1027,3 +1066,45 @@ func (o *Remote) Prune(callbacks *RemoteCallbacks) error {
 	}
 	return nil
 }
+
+// DefaultApplyOptions returns default options for remote create
+func DefaultRemoteCreateOptions() (*RemoteCreateOptions, error) {
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+
+	opts := C.git_remote_create_options{}
+	ecode := C.git_remote_create_options_init(&opts, C.GIT_REMOTE_CREATE_OPTIONS_VERSION)
+	if ecode < 0 {
+		return nil, MakeGitError(ecode)
+	}
+
+	return &RemoteCreateOptions{
+		Flags: RemoteCreateOptionsFlag(opts.flags),
+	}, nil
+}
+
+func populateRemoteCreateOptions(copts *C.git_remote_create_options, opts *RemoteCreateOptions, repo *Repository) *C.git_remote_create_options {
+	C.git_remote_create_options_init(copts, C.GIT_REMOTE_CREATE_OPTIONS_VERSION)
+	if opts == nil {
+		return nil
+	}
+
+	var cRepository *C.git_repository
+	if repo != nil {
+		cRepository = repo.ptr
+	}
+	copts.repository = cRepository
+	copts.name = C.CString(opts.Name)
+	copts.fetchspec = C.CString(opts.FetchSpec)
+	copts.flags = C.uint(opts.Flags)
+
+	return copts
+}
+
+func freeRemoteCreateOptions(ptr *C.git_remote_create_options) {
+	if ptr == nil {
+		return
+	}
+	C.free(unsafe.Pointer(ptr.name))
+	C.free(unsafe.Pointer(ptr.fetchspec))
+}


Test patch:
diff --git a/remote_test.go b/remote_test.go
index 16ac06b..22fd292 100644
--- a/remote_test.go
+++ b/remote_test.go
@@ -80,6 +80,28 @@ func TestRemoteConnect(t *testing.T) {
 	checkFatal(t, err)
 }
 
+func TestRemoteConnectOption(t *testing.T) {
+	t.Parallel()
+	repo := createTestRepo(t)
+	defer cleanupTestRepo(t, repo)
+
+	config, err := repo.Config()
+	checkFatal(t, err)
+	err = config.SetString("url.git@github.com:.insteadof", "https://github.com/")
+	checkFatal(t, err)
+
+	option, err := DefaultRemoteCreateOptions()
+	checkFatal(t, err)
+	option.Name = "origin"
+	option.Flags = RemoteCreateSkipInsteadof
+
+	remote, err := repo.Remotes.CreateWithOptions("https://github.com/libgit2/TestGitRepository", option)
+	checkFatal(t, err)
+
+	err = remote.ConnectFetch(nil, nil, nil)
+	checkFatal(t, err)
+}
+
 func TestRemoteLs(t *testing.T) {
 	t.Parallel()
 	repo := createTestRepo(t)