Merge remote-tracking branch 'origin/master' into next
This commit is contained in:
commit
0522886781
|
@ -9,6 +9,7 @@ go:
|
|||
- 1.2
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.5
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
|
|
|
@ -40,7 +40,7 @@ Parallelism and network operations
|
|||
----------------------------------
|
||||
|
||||
libgit2 uses OpenSSL and LibSSH2 for performing encrypted network connections. For now, git2go asks libgit2 to set locking for OpenSSL. This makes HTTPS connections thread-safe, but it is fragile and will likely stop doing it soon. This may also make SSH connections thread-safe if your copy of libssh2 is linked against OpenSSL. Check libgit2's `THREADSAFE.md` for more information.
|
||||
[
|
||||
|
||||
Running the tests
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ func (repo *Repository) CreateBranch(branchName string, target *Commit, force bo
|
|||
|
||||
var ptr *C.git_reference
|
||||
cBranchName := C.CString(branchName)
|
||||
defer C.free(unsafe.Pointer(cBranchName))
|
||||
cForce := cbool(force)
|
||||
|
||||
runtime.LockOSThread()
|
||||
|
@ -120,6 +121,7 @@ func (b *Branch) Delete() error {
|
|||
func (b *Branch) Move(newBranchName string, force bool) (*Branch, error) {
|
||||
var ptr *C.git_reference
|
||||
cNewBranchName := C.CString(newBranchName)
|
||||
defer C.free(unsafe.Pointer(cNewBranchName))
|
||||
cForce := cbool(force)
|
||||
|
||||
runtime.LockOSThread()
|
||||
|
@ -152,6 +154,7 @@ func (repo *Repository) LookupBranch(branchName string, bt BranchType) (*Branch,
|
|||
var ptr *C.git_reference
|
||||
|
||||
cName := C.CString(branchName)
|
||||
defer C.free(unsafe.Pointer(cName))
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
@ -180,6 +183,7 @@ func (b *Branch) Name() (string, error) {
|
|||
|
||||
func (repo *Repository) RemoteName(canonicalBranchName string) (string, error) {
|
||||
cName := C.CString(canonicalBranchName)
|
||||
defer C.free(unsafe.Pointer(cName))
|
||||
|
||||
nameBuf := C.git_buf{}
|
||||
|
||||
|
@ -197,6 +201,7 @@ func (repo *Repository) RemoteName(canonicalBranchName string) (string, error) {
|
|||
|
||||
func (b *Branch) SetUpstream(upstreamName string) error {
|
||||
cName := C.CString(upstreamName)
|
||||
defer C.free(unsafe.Pointer(cName))
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
@ -223,6 +228,7 @@ func (b *Branch) Upstream() (*Reference, error) {
|
|||
|
||||
func (repo *Repository) UpstreamName(canonicalBranchName string) (string, error) {
|
||||
cName := C.CString(canonicalBranchName)
|
||||
defer C.free(unsafe.Pointer(cName))
|
||||
|
||||
nameBuf := C.git_buf{}
|
||||
|
||||
|
|
62
clone.go
62
clone.go
|
@ -3,6 +3,7 @@ package git
|
|||
/*
|
||||
#include <git2.h>
|
||||
|
||||
extern void _go_git_populate_remote_cb(git_clone_options *opts);
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
|
@ -10,13 +11,14 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
type RemoteCreateCallback func(repo *Repository, name, url string) (*Remote, ErrorCode)
|
||||
|
||||
type CloneOptions struct {
|
||||
*CheckoutOpts
|
||||
*FetchOptions
|
||||
Bare bool
|
||||
CheckoutBranch string
|
||||
RemoteCreateCallback C.git_remote_create_cb
|
||||
RemoteCreatePayload unsafe.Pointer
|
||||
RemoteCreateCallback RemoteCreateCallback
|
||||
}
|
||||
|
||||
func Clone(url string, path string, options *CloneOptions) (*Repository, error) {
|
||||
|
@ -28,6 +30,7 @@ func Clone(url string, path string, options *CloneOptions) (*Repository, error)
|
|||
|
||||
copts := (*C.git_clone_options)(C.calloc(1, C.size_t(unsafe.Sizeof(C.git_clone_options{}))))
|
||||
populateCloneOptions(copts, options)
|
||||
defer freeCloneOptions(copts)
|
||||
|
||||
if len(options.CheckoutBranch) != 0 {
|
||||
copts.checkout_branch = C.CString(options.CheckoutBranch)
|
||||
|
@ -35,11 +38,10 @@ func Clone(url string, path string, options *CloneOptions) (*Repository, error)
|
|||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
var ptr *C.git_repository
|
||||
ret := C.git_clone(&ptr, curl, cpath, copts)
|
||||
freeCheckoutOpts(&copts.checkout_opts)
|
||||
C.free(unsafe.Pointer(copts.checkout_branch))
|
||||
C.free(unsafe.Pointer(copts))
|
||||
|
||||
if ret < 0 {
|
||||
return nil, MakeGitError(ret)
|
||||
|
@ -48,6 +50,33 @@ func Clone(url string, path string, options *CloneOptions) (*Repository, error)
|
|||
return newRepositoryFromC(ptr), nil
|
||||
}
|
||||
|
||||
//export remoteCreateCallback
|
||||
func remoteCreateCallback(cremote unsafe.Pointer, crepo unsafe.Pointer, cname, curl *C.char, payload unsafe.Pointer) C.int {
|
||||
name := C.GoString(cname)
|
||||
url := C.GoString(curl)
|
||||
repo := newRepositoryFromC((*C.git_repository)(crepo))
|
||||
// We don't own this repository, so make sure we don't try to free it
|
||||
runtime.SetFinalizer(repo, nil)
|
||||
|
||||
if opts, ok := pointerHandles.Get(payload).(CloneOptions); ok {
|
||||
remote, err := opts.RemoteCreateCallback(repo, name, url)
|
||||
// clear finalizer as the calling C function will
|
||||
// free the remote itself
|
||||
runtime.SetFinalizer(remote, nil)
|
||||
|
||||
if err == ErrOk && remote != nil {
|
||||
cptr := (**C.git_remote)(cremote)
|
||||
*cptr = remote.ptr
|
||||
} else if err == ErrOk && remote == nil {
|
||||
panic("no remote created by callback")
|
||||
}
|
||||
|
||||
return C.int(err)
|
||||
} else {
|
||||
panic("invalid remote create callback")
|
||||
}
|
||||
}
|
||||
|
||||
func populateCloneOptions(ptr *C.git_clone_options, opts *CloneOptions) {
|
||||
C.git_clone_init_options(ptr, C.GIT_CLONE_OPTIONS_VERSION)
|
||||
|
||||
|
@ -59,12 +88,23 @@ func populateCloneOptions(ptr *C.git_clone_options, opts *CloneOptions) {
|
|||
ptr.bare = cbool(opts.Bare)
|
||||
|
||||
if opts.RemoteCreateCallback != nil {
|
||||
ptr.remote_cb = opts.RemoteCreateCallback
|
||||
defer C.free(unsafe.Pointer(opts.RemoteCreateCallback))
|
||||
|
||||
if opts.RemoteCreatePayload != nil {
|
||||
ptr.remote_cb_payload = opts.RemoteCreatePayload
|
||||
defer C.free(opts.RemoteCreatePayload)
|
||||
}
|
||||
// Go v1.1 does not allow to assign a C function pointer
|
||||
C._go_git_populate_remote_cb(ptr)
|
||||
ptr.remote_cb_payload = pointerHandles.Track(*opts)
|
||||
}
|
||||
}
|
||||
|
||||
func freeCloneOptions(ptr *C.git_clone_options) {
|
||||
if ptr == nil {
|
||||
return
|
||||
}
|
||||
|
||||
freeCheckoutOpts(&ptr.checkout_opts)
|
||||
|
||||
if ptr.remote_cb_payload != nil {
|
||||
pointerHandles.Untrack(ptr.remote_cb_payload)
|
||||
}
|
||||
|
||||
C.free(unsafe.Pointer(ptr.checkout_branch))
|
||||
C.free(unsafe.Pointer(ptr))
|
||||
}
|
||||
|
|
|
@ -5,8 +5,11 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
func TestClone(t *testing.T) {
|
||||
const (
|
||||
REMOTENAME = "testremote"
|
||||
)
|
||||
|
||||
func TestClone(t *testing.T) {
|
||||
repo := createTestRepo(t)
|
||||
defer cleanupTestRepo(t, repo)
|
||||
|
||||
|
@ -30,3 +33,43 @@ func TestClone(t *testing.T) {
|
|||
t.Fatal("reference in clone does not match original ref")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloneWithCallback(t *testing.T) {
|
||||
testPayload := 0
|
||||
|
||||
repo := createTestRepo(t)
|
||||
defer cleanupTestRepo(t, repo)
|
||||
|
||||
seedTestRepo(t, repo)
|
||||
|
||||
path, err := ioutil.TempDir("", "git2go")
|
||||
checkFatal(t, err)
|
||||
|
||||
opts := CloneOptions{
|
||||
Bare: true,
|
||||
RemoteCreateCallback: func(r *Repository, name, url string) (*Remote, ErrorCode) {
|
||||
testPayload += 1
|
||||
|
||||
remote, err := r.Remotes.Create(REMOTENAME, url)
|
||||
if err != nil {
|
||||
return nil, ErrGeneric
|
||||
}
|
||||
|
||||
return remote, ErrOk
|
||||
},
|
||||
}
|
||||
|
||||
repo2, err := Clone(repo.Path(), path, &opts)
|
||||
defer cleanupTestRepo(t, repo2)
|
||||
|
||||
checkFatal(t, err)
|
||||
|
||||
if testPayload != 1 {
|
||||
t.Fatal("Payload's value has not been changed")
|
||||
}
|
||||
|
||||
remote, err := repo2.Remotes.Lookup(REMOTENAME)
|
||||
if err != nil || remote == nil {
|
||||
t.Fatal("Remote was not created properly")
|
||||
}
|
||||
}
|
||||
|
|
1
merge.go
1
merge.go
|
@ -394,6 +394,7 @@ func MergeFile(ancestor MergeFileInput, ours MergeFileInput, theirs MergeFileInp
|
|||
return nil, MakeGitError(ecode)
|
||||
}
|
||||
populateCMergeFileOptions(copts, *options)
|
||||
defer freeCMergeFileOptions(copts)
|
||||
}
|
||||
|
||||
runtime.LockOSThread()
|
||||
|
|
|
@ -13,9 +13,9 @@ if [ "x$TRAVIS_BRANCH" = "xnext" ]; then
|
|||
fi
|
||||
|
||||
cd "${HOME}"
|
||||
wget -O libgit2-0.22.3.tar.gz https://github.com/libgit2/libgit2/archive/v0.22.1.tar.gz
|
||||
tar -xzvf libgit2-0.22.3.tar.gz
|
||||
cd libgit2-0.22.1 && mkdir build && cd build
|
||||
wget -O libgit2-0.23.1.tar.gz https://github.com/libgit2/libgit2/archive/v0.23.1.tar.gz
|
||||
tar -xzvf libgit2-0.23.1.tar.gz
|
||||
cd libgit2-0.23.1 && mkdir build && cd build
|
||||
cmake -DTHREADSAFE=ON -DBUILD_CLAR=OFF -DCMAKE_BUILD_TYPE="RelWithDebInfo" .. && make && sudo make install
|
||||
sudo ldconfig
|
||||
cd "${TRAVIS_BUILD_DIR}"
|
||||
|
|
36
status.go
36
status.go
|
@ -126,34 +126,24 @@ type StatusOptions struct {
|
|||
Pathspec []string
|
||||
}
|
||||
|
||||
func (opts *StatusOptions) toC() *C.git_status_options {
|
||||
if opts == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cpathspec := C.git_strarray{}
|
||||
if opts.Pathspec != nil {
|
||||
cpathspec.count = C.size_t(len(opts.Pathspec))
|
||||
cpathspec.strings = makeCStringsFromStrings(opts.Pathspec)
|
||||
defer freeStrarray(&cpathspec)
|
||||
}
|
||||
|
||||
copts := &C.git_status_options{
|
||||
version: C.GIT_STATUS_OPTIONS_VERSION,
|
||||
show: C.git_status_show_t(opts.Show),
|
||||
flags: C.uint(opts.Flags),
|
||||
pathspec: cpathspec,
|
||||
}
|
||||
|
||||
return copts
|
||||
}
|
||||
|
||||
func (v *Repository) StatusList(opts *StatusOptions) (*StatusList, error) {
|
||||
var ptr *C.git_status_list
|
||||
var copts *C.git_status_options
|
||||
|
||||
if opts != nil {
|
||||
copts = opts.toC()
|
||||
cpathspec := C.git_strarray{}
|
||||
if opts.Pathspec != nil {
|
||||
cpathspec.count = C.size_t(len(opts.Pathspec))
|
||||
cpathspec.strings = makeCStringsFromStrings(opts.Pathspec)
|
||||
defer freeStrarray(&cpathspec)
|
||||
}
|
||||
|
||||
copts = &C.git_status_options{
|
||||
version: C.GIT_STATUS_OPTIONS_VERSION,
|
||||
show: C.git_status_show_t(opts.Show),
|
||||
flags: C.uint(opts.Flags),
|
||||
pathspec: cpathspec,
|
||||
}
|
||||
} else {
|
||||
copts = &C.git_status_options{}
|
||||
ret := C.git_status_init_options(copts, C.GIT_STATUS_OPTIONS_VERSION)
|
||||
|
|
4
walk.go
4
walk.go
|
@ -173,6 +173,10 @@ func (v *RevWalk) Iterate(fun RevWalkIterator) (err error) {
|
|||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
if err.(GitError).Code == ErrIterOver {
|
||||
err = nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
|
||||
typedef int (*gogit_submodule_cbk)(git_submodule *sm, const char *name, void *payload);
|
||||
|
||||
void _go_git_populate_remote_cb(git_clone_options *opts)
|
||||
{
|
||||
opts->remote_cb = (git_remote_create_cb)remoteCreateCallback;
|
||||
}
|
||||
|
||||
int _go_git_visit_submodule(git_repository *repo, void *fct)
|
||||
{
|
||||
return git_submodule_foreach(repo, (gogit_submodule_cbk)&SubmoduleVisitor, fct);
|
||||
|
|
Loading…
Reference in New Issue