Merge remote-tracking branch 'origin/master' into next
This commit is contained in:
commit
0522886781
|
@ -9,6 +9,7 @@ go:
|
||||||
- 1.2
|
- 1.2
|
||||||
- 1.3
|
- 1.3
|
||||||
- 1.4
|
- 1.4
|
||||||
|
- 1.5
|
||||||
- tip
|
- tip
|
||||||
|
|
||||||
matrix:
|
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.
|
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
|
Running the tests
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,7 @@ func (repo *Repository) CreateBranch(branchName string, target *Commit, force bo
|
||||||
|
|
||||||
var ptr *C.git_reference
|
var ptr *C.git_reference
|
||||||
cBranchName := C.CString(branchName)
|
cBranchName := C.CString(branchName)
|
||||||
|
defer C.free(unsafe.Pointer(cBranchName))
|
||||||
cForce := cbool(force)
|
cForce := cbool(force)
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
@ -120,6 +121,7 @@ func (b *Branch) Delete() error {
|
||||||
func (b *Branch) Move(newBranchName string, force bool) (*Branch, error) {
|
func (b *Branch) Move(newBranchName string, force bool) (*Branch, error) {
|
||||||
var ptr *C.git_reference
|
var ptr *C.git_reference
|
||||||
cNewBranchName := C.CString(newBranchName)
|
cNewBranchName := C.CString(newBranchName)
|
||||||
|
defer C.free(unsafe.Pointer(cNewBranchName))
|
||||||
cForce := cbool(force)
|
cForce := cbool(force)
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
@ -152,6 +154,7 @@ func (repo *Repository) LookupBranch(branchName string, bt BranchType) (*Branch,
|
||||||
var ptr *C.git_reference
|
var ptr *C.git_reference
|
||||||
|
|
||||||
cName := C.CString(branchName)
|
cName := C.CString(branchName)
|
||||||
|
defer C.free(unsafe.Pointer(cName))
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
@ -180,6 +183,7 @@ func (b *Branch) Name() (string, error) {
|
||||||
|
|
||||||
func (repo *Repository) RemoteName(canonicalBranchName string) (string, error) {
|
func (repo *Repository) RemoteName(canonicalBranchName string) (string, error) {
|
||||||
cName := C.CString(canonicalBranchName)
|
cName := C.CString(canonicalBranchName)
|
||||||
|
defer C.free(unsafe.Pointer(cName))
|
||||||
|
|
||||||
nameBuf := C.git_buf{}
|
nameBuf := C.git_buf{}
|
||||||
|
|
||||||
|
@ -197,6 +201,7 @@ func (repo *Repository) RemoteName(canonicalBranchName string) (string, error) {
|
||||||
|
|
||||||
func (b *Branch) SetUpstream(upstreamName string) error {
|
func (b *Branch) SetUpstream(upstreamName string) error {
|
||||||
cName := C.CString(upstreamName)
|
cName := C.CString(upstreamName)
|
||||||
|
defer C.free(unsafe.Pointer(cName))
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
@ -223,6 +228,7 @@ func (b *Branch) Upstream() (*Reference, error) {
|
||||||
|
|
||||||
func (repo *Repository) UpstreamName(canonicalBranchName string) (string, error) {
|
func (repo *Repository) UpstreamName(canonicalBranchName string) (string, error) {
|
||||||
cName := C.CString(canonicalBranchName)
|
cName := C.CString(canonicalBranchName)
|
||||||
|
defer C.free(unsafe.Pointer(cName))
|
||||||
|
|
||||||
nameBuf := C.git_buf{}
|
nameBuf := C.git_buf{}
|
||||||
|
|
||||||
|
|
62
clone.go
62
clone.go
|
@ -3,6 +3,7 @@ package git
|
||||||
/*
|
/*
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
|
|
||||||
|
extern void _go_git_populate_remote_cb(git_clone_options *opts);
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
|
@ -10,13 +11,14 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type RemoteCreateCallback func(repo *Repository, name, url string) (*Remote, ErrorCode)
|
||||||
|
|
||||||
type CloneOptions struct {
|
type CloneOptions struct {
|
||||||
*CheckoutOpts
|
*CheckoutOpts
|
||||||
*FetchOptions
|
*FetchOptions
|
||||||
Bare bool
|
Bare bool
|
||||||
CheckoutBranch string
|
CheckoutBranch string
|
||||||
RemoteCreateCallback C.git_remote_create_cb
|
RemoteCreateCallback RemoteCreateCallback
|
||||||
RemoteCreatePayload unsafe.Pointer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Clone(url string, path string, options *CloneOptions) (*Repository, error) {
|
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{}))))
|
copts := (*C.git_clone_options)(C.calloc(1, C.size_t(unsafe.Sizeof(C.git_clone_options{}))))
|
||||||
populateCloneOptions(copts, options)
|
populateCloneOptions(copts, options)
|
||||||
|
defer freeCloneOptions(copts)
|
||||||
|
|
||||||
if len(options.CheckoutBranch) != 0 {
|
if len(options.CheckoutBranch) != 0 {
|
||||||
copts.checkout_branch = C.CString(options.CheckoutBranch)
|
copts.checkout_branch = C.CString(options.CheckoutBranch)
|
||||||
|
@ -35,11 +38,10 @@ func Clone(url string, path string, options *CloneOptions) (*Repository, error)
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
var ptr *C.git_repository
|
var ptr *C.git_repository
|
||||||
ret := C.git_clone(&ptr, curl, cpath, copts)
|
ret := C.git_clone(&ptr, curl, cpath, copts)
|
||||||
freeCheckoutOpts(&copts.checkout_opts)
|
freeCheckoutOpts(&copts.checkout_opts)
|
||||||
C.free(unsafe.Pointer(copts.checkout_branch))
|
|
||||||
C.free(unsafe.Pointer(copts))
|
|
||||||
|
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return nil, MakeGitError(ret)
|
return nil, MakeGitError(ret)
|
||||||
|
@ -48,6 +50,33 @@ func Clone(url string, path string, options *CloneOptions) (*Repository, error)
|
||||||
return newRepositoryFromC(ptr), nil
|
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) {
|
func populateCloneOptions(ptr *C.git_clone_options, opts *CloneOptions) {
|
||||||
C.git_clone_init_options(ptr, C.GIT_CLONE_OPTIONS_VERSION)
|
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)
|
ptr.bare = cbool(opts.Bare)
|
||||||
|
|
||||||
if opts.RemoteCreateCallback != nil {
|
if opts.RemoteCreateCallback != nil {
|
||||||
ptr.remote_cb = opts.RemoteCreateCallback
|
// Go v1.1 does not allow to assign a C function pointer
|
||||||
defer C.free(unsafe.Pointer(opts.RemoteCreateCallback))
|
C._go_git_populate_remote_cb(ptr)
|
||||||
|
ptr.remote_cb_payload = pointerHandles.Track(*opts)
|
||||||
if opts.RemoteCreatePayload != nil {
|
|
||||||
ptr.remote_cb_payload = opts.RemoteCreatePayload
|
|
||||||
defer C.free(opts.RemoteCreatePayload)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestClone(t *testing.T) {
|
const (
|
||||||
|
REMOTENAME = "testremote"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClone(t *testing.T) {
|
||||||
repo := createTestRepo(t)
|
repo := createTestRepo(t)
|
||||||
defer cleanupTestRepo(t, repo)
|
defer cleanupTestRepo(t, repo)
|
||||||
|
|
||||||
|
@ -30,3 +33,43 @@ func TestClone(t *testing.T) {
|
||||||
t.Fatal("reference in clone does not match original ref")
|
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)
|
return nil, MakeGitError(ecode)
|
||||||
}
|
}
|
||||||
populateCMergeFileOptions(copts, *options)
|
populateCMergeFileOptions(copts, *options)
|
||||||
|
defer freeCMergeFileOptions(copts)
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
|
|
@ -13,9 +13,9 @@ if [ "x$TRAVIS_BRANCH" = "xnext" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd "${HOME}"
|
cd "${HOME}"
|
||||||
wget -O libgit2-0.22.3.tar.gz https://github.com/libgit2/libgit2/archive/v0.22.1.tar.gz
|
wget -O libgit2-0.23.1.tar.gz https://github.com/libgit2/libgit2/archive/v0.23.1.tar.gz
|
||||||
tar -xzvf libgit2-0.22.3.tar.gz
|
tar -xzvf libgit2-0.23.1.tar.gz
|
||||||
cd libgit2-0.22.1 && mkdir build && cd build
|
cd libgit2-0.23.1 && mkdir build && cd build
|
||||||
cmake -DTHREADSAFE=ON -DBUILD_CLAR=OFF -DCMAKE_BUILD_TYPE="RelWithDebInfo" .. && make && sudo make install
|
cmake -DTHREADSAFE=ON -DBUILD_CLAR=OFF -DCMAKE_BUILD_TYPE="RelWithDebInfo" .. && make && sudo make install
|
||||||
sudo ldconfig
|
sudo ldconfig
|
||||||
cd "${TRAVIS_BUILD_DIR}"
|
cd "${TRAVIS_BUILD_DIR}"
|
||||||
|
|
36
status.go
36
status.go
|
@ -126,34 +126,24 @@ type StatusOptions struct {
|
||||||
Pathspec []string
|
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) {
|
func (v *Repository) StatusList(opts *StatusOptions) (*StatusList, error) {
|
||||||
var ptr *C.git_status_list
|
var ptr *C.git_status_list
|
||||||
var copts *C.git_status_options
|
var copts *C.git_status_options
|
||||||
|
|
||||||
if opts != nil {
|
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 {
|
} else {
|
||||||
copts = &C.git_status_options{}
|
copts = &C.git_status_options{}
|
||||||
ret := C.git_status_init_options(copts, C.GIT_STATUS_OPTIONS_VERSION)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err.(GitError).Code == ErrIterOver {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
|
|
||||||
typedef int (*gogit_submodule_cbk)(git_submodule *sm, const char *name, void *payload);
|
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)
|
int _go_git_visit_submodule(git_repository *repo, void *fct)
|
||||||
{
|
{
|
||||||
return git_submodule_foreach(repo, (gogit_submodule_cbk)&SubmoduleVisitor, fct);
|
return git_submodule_foreach(repo, (gogit_submodule_cbk)&SubmoduleVisitor, fct);
|
||||||
|
|
Loading…
Reference in New Issue