bugfix: HTTPS Clone fails with remote pointer not found using Go transport (#836) (#842) (#847)

Fixes: #836

Changes:

* adding a weak bool param for Remote
* create a new remote in the smartTransportCallback incase one is not found

(cherry picked from commit 0e8009f00a)

Co-authored-by: Yashodhan Ghadge <codexetreme@users.noreply.github.com>
Co-authored-by: lhchavez <lhchavez@lhchavez.com>
This commit is contained in:
github-actions[bot] 2021-11-09 06:22:32 -08:00 committed by GitHub
parent 7145746145
commit 34d31c0438
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 3 deletions

View File

@ -2,6 +2,7 @@ package git
import ( import (
"io/ioutil" "io/ioutil"
"os"
"testing" "testing"
) )
@ -76,3 +77,17 @@ func TestCloneWithCallback(t *testing.T) {
} }
defer remote.Free() defer remote.Free()
} }
// TestCloneWithExternalHTTPUrl
func TestCloneWithExternalHTTPUrl(t *testing.T) {
path, err := ioutil.TempDir("", "git2go")
defer os.RemoveAll(path)
// clone the repo
url := "https://github.com/libgit2/TestGitRepository"
_, err = Clone(url, path, &CloneOptions{})
if err != nil {
t.Fatal("cannot clone remote repo via https, error: ", err)
}
}

View File

@ -182,6 +182,9 @@ type Remote struct {
ptr *C.git_remote ptr *C.git_remote
callbacks RemoteCallbacks callbacks RemoteCallbacks
repo *Repository repo *Repository
// weak indicates that a remote is a weak pointer and should not be
// freed.
weak bool
} }
type remotePointerList struct { type remotePointerList struct {
@ -592,6 +595,9 @@ func (r *Remote) free() {
// Free releases the resources of the Remote. // Free releases the resources of the Remote.
func (r *Remote) Free() { func (r *Remote) Free() {
r.repo.Remotes.untrackRemote(r) r.repo.Remotes.untrackRemote(r)
if r.weak {
return
}
r.free() r.free()
} }
@ -1221,3 +1227,12 @@ func freeRemoteCreateOptions(ptr *C.git_remote_create_options) {
C.free(unsafe.Pointer(ptr.name)) C.free(unsafe.Pointer(ptr.name))
C.free(unsafe.Pointer(ptr.fetchspec)) C.free(unsafe.Pointer(ptr.fetchspec))
} }
// createNewEmptyRemote used to get a new empty object of *Remote
func createNewEmptyRemote() *Remote {
return &Remote{
callbacks: RemoteCallbacks{},
repo: nil,
weak: false,
}
}

View File

@ -22,7 +22,6 @@ void _go_git_setup_smart_subtransport_stream(_go_managed_smart_subtransport_stre
*/ */
import "C" import "C"
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"reflect" "reflect"
@ -296,8 +295,10 @@ func smartTransportCallback(
registeredSmartTransport := pointerHandles.Get(handle).(*RegisteredSmartTransport) registeredSmartTransport := pointerHandles.Get(handle).(*RegisteredSmartTransport)
remote, ok := remotePointers.get(owner) remote, ok := remotePointers.get(owner)
if !ok { if !ok {
err := errors.New("remote pointer not found") // create a new empty remote and set it
return setCallbackError(errorMessage, err) // as a weak pointer, so that control stays in golang
remote = createNewEmptyRemote()
remote.weak = true
} }
managed := &managedSmartSubtransport{ managed := &managedSmartSubtransport{