From 555158189319e80d2e83fa928b72ed54c0191d17 Mon Sep 17 00:00:00 2001 From: Byoungchan Lee Date: Mon, 1 Feb 2021 22:16:46 +0900 Subject: [PATCH 1/4] Support git_remote_create_with_opts --- remote.go | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ remote_test.go | 23 +++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/remote.go b/remote.go index 1887f79..cc9ff98 100644 --- a/remote.go +++ b/remote.go @@ -18,6 +18,23 @@ import ( "unsafe" ) +type RemoteCreate uint + +const ( + // Ignore the repository apply.insteadOf configuration + RemoteCreateSkipInsteadof RemoteCreate = C.GIT_REMOTE_CREATE_SKIP_INSTEADOF + // Don't build a fetchspec from the name if none is set + RemoteCreateSkipDefaultFetchspec RemoteCreate = C.GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC +) + +// RemoteCreateOptions contains options for creating a remote +type RemoteCreateOptions struct { + Repository *Repository + Name string + FetchSpec string + Flags RemoteCreate +} + type TransferProgress struct { TotalObjects uint IndexedObjects uint @@ -539,6 +556,26 @@ func (c *RemoteCollection) Create(name string, url string) (*Remote, error) { return remote, nil } +func (c *RemoteCollection) CreateOptions(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() + + opts := remoteCreateOptionsToC(option) + defer freeRemoteCreateOptions(opts) + ret := C.git_remote_create_with_opts(&remote.ptr, curl, opts) + 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 +1064,46 @@ 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 int(ecode) != 0 { + return nil, MakeGitError(ecode) + } + + return &RemoteCreateOptions{ + Repository: nil, + Flags: 0, + }, nil +} + +func remoteCreateOptionsToC(opts *RemoteCreateOptions) (copts *C.git_remote_create_options) { + if opts == nil { + return + } + + cName := C.CString(opts.Name) + cFetchSpec := C.CString(opts.FetchSpec) + + copts = &C.git_remote_create_options{ + version: C.GIT_REMOTE_CREATE_OPTIONS_VERSION, + repository: opts.Repository.ptr, + name: cName, + fetchspec: cFetchSpec, + 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)) +} diff --git a/remote_test.go b/remote_test.go index 16ac06b..0fb971d 100644 --- a/remote_test.go +++ b/remote_test.go @@ -80,6 +80,29 @@ 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.Repository = repo + option.Name = "origin" + option.Flags = RemoteCreateSkipInsteadof + + remote, err := repo.Remotes.CreateOptions("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) -- 2.45.2 From 96aacc1f1de455369931f689fa0ce031b688adb4 Mon Sep 17 00:00:00 2001 From: Byoungchan Lee Date: Wed, 3 Feb 2021 23:18:44 +0900 Subject: [PATCH 2/4] Updated remote.go to handle various comments on code review. - Use consistent names for type/function names. - Removes unnecessary Repository pointers that can be collected from RemoteCollection. - Add runtime.KeepAlive to make the pointer happy. --- remote.go | 24 ++++++++++++------------ remote_test.go | 3 +-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/remote.go b/remote.go index cc9ff98..40e6da7 100644 --- a/remote.go +++ b/remote.go @@ -18,21 +18,21 @@ import ( "unsafe" ) -type RemoteCreate uint +// RemoteCreateOptionsFlag is Remote creation options flags +type RemoteCreateOptionsFlag uint const ( // Ignore the repository apply.insteadOf configuration - RemoteCreateSkipInsteadof RemoteCreate = C.GIT_REMOTE_CREATE_SKIP_INSTEADOF + RemoteCreateSkipInsteadof RemoteCreateOptionsFlag = C.GIT_REMOTE_CREATE_SKIP_INSTEADOF // Don't build a fetchspec from the name if none is set - RemoteCreateSkipDefaultFetchspec RemoteCreate = C.GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC + RemoteCreateSkipDefaultFetchspec RemoteCreateOptionsFlag = C.GIT_REMOTE_CREATE_SKIP_DEFAULT_FETCHSPEC ) // RemoteCreateOptions contains options for creating a remote type RemoteCreateOptions struct { - Repository *Repository Name string FetchSpec string - Flags RemoteCreate + Flags RemoteCreateOptionsFlag } type TransferProgress struct { @@ -556,7 +556,7 @@ func (c *RemoteCollection) Create(name string, url string) (*Remote, error) { return remote, nil } -func (c *RemoteCollection) CreateOptions(url string, option *RemoteCreateOptions) (*Remote, error) { +func (c *RemoteCollection) CreateWithOptions(url string, option *RemoteCreateOptions) (*Remote, error) { remote := &Remote{repo: c.repo} curl := C.CString(url) @@ -565,9 +565,10 @@ func (c *RemoteCollection) CreateOptions(url string, option *RemoteCreateOptions runtime.LockOSThread() defer runtime.UnlockOSThread() - opts := remoteCreateOptionsToC(option) + opts := populateRemoteCreateOptions(c.repo, option) defer freeRemoteCreateOptions(opts) ret := C.git_remote_create_with_opts(&remote.ptr, curl, opts) + runtime.KeepAlive(c.repo) if ret < 0 { return nil, MakeGitError(ret) } @@ -1077,13 +1078,12 @@ func DefaultRemoteCreateOptions() (*RemoteCreateOptions, error) { } return &RemoteCreateOptions{ - Repository: nil, - Flags: 0, + Flags: RemoteCreateOptionsFlag(opts.flags), }, nil } -func remoteCreateOptionsToC(opts *RemoteCreateOptions) (copts *C.git_remote_create_options) { - if opts == nil { +func populateRemoteCreateOptions(repository *Repository, opts *RemoteCreateOptions) (copts *C.git_remote_create_options) { + if repository == nil || opts == nil { return } @@ -1092,7 +1092,7 @@ func remoteCreateOptionsToC(opts *RemoteCreateOptions) (copts *C.git_remote_crea copts = &C.git_remote_create_options{ version: C.GIT_REMOTE_CREATE_OPTIONS_VERSION, - repository: opts.Repository.ptr, + repository: repository.ptr, name: cName, fetchspec: cFetchSpec, flags: C.uint(opts.Flags), diff --git a/remote_test.go b/remote_test.go index 0fb971d..22fd292 100644 --- a/remote_test.go +++ b/remote_test.go @@ -92,11 +92,10 @@ func TestRemoteConnectOption(t *testing.T) { option, err := DefaultRemoteCreateOptions() checkFatal(t, err) - option.Repository = repo option.Name = "origin" option.Flags = RemoteCreateSkipInsteadof - remote, err := repo.Remotes.CreateOptions("https://github.com/libgit2/TestGitRepository", option) + remote, err := repo.Remotes.CreateWithOptions("https://github.com/libgit2/TestGitRepository", option) checkFatal(t, err) err = remote.ConnectFetch(nil, nil, nil) -- 2.45.2 From 863c15bbc1e73a4508fbc046c927191a25034b78 Mon Sep 17 00:00:00 2001 From: Byoungchan Lee Date: Wed, 3 Feb 2021 23:33:11 +0900 Subject: [PATCH 3/4] Updated remote.go to add a comment for the public API --- remote.go | 1 + 1 file changed, 1 insertion(+) diff --git a/remote.go b/remote.go index 40e6da7..a2fbaff 100644 --- a/remote.go +++ b/remote.go @@ -556,6 +556,7 @@ 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} -- 2.45.2 From 38f8bdaa95bf181a1a4574e6e9eaecba62315eaa Mon Sep 17 00:00:00 2001 From: Byoungchan Lee Date: Thu, 4 Feb 2021 08:08:53 +0900 Subject: [PATCH 4/4] Rewrite populateRemoteCreateOptions to be similar to other populateXxxOptions. Also, handling the return code of libgit2 has changed. --- remote.go | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/remote.go b/remote.go index a2fbaff..08d8414 100644 --- a/remote.go +++ b/remote.go @@ -566,9 +566,9 @@ func (c *RemoteCollection) CreateWithOptions(url string, option *RemoteCreateOpt runtime.LockOSThread() defer runtime.UnlockOSThread() - opts := populateRemoteCreateOptions(c.repo, option) - defer freeRemoteCreateOptions(opts) - ret := C.git_remote_create_with_opts(&remote.ptr, curl, opts) + 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) @@ -1074,7 +1074,7 @@ func DefaultRemoteCreateOptions() (*RemoteCreateOptions, error) { opts := C.git_remote_create_options{} ecode := C.git_remote_create_options_init(&opts, C.GIT_REMOTE_CREATE_OPTIONS_VERSION) - if int(ecode) != 0 { + if ecode < 0 { return nil, MakeGitError(ecode) } @@ -1083,21 +1083,21 @@ func DefaultRemoteCreateOptions() (*RemoteCreateOptions, error) { }, nil } -func populateRemoteCreateOptions(repository *Repository, opts *RemoteCreateOptions) (copts *C.git_remote_create_options) { - if repository == nil || opts == nil { - return +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 } - cName := C.CString(opts.Name) - cFetchSpec := C.CString(opts.FetchSpec) - - copts = &C.git_remote_create_options{ - version: C.GIT_REMOTE_CREATE_OPTIONS_VERSION, - repository: repository.ptr, - name: cName, - fetchspec: cFetchSpec, - flags: C.uint(opts.Flags), + 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 } -- 2.45.2