Update to 1dc4491

This commit is contained in:
Carlos Martín Nieto 2016-04-21 16:34:51 +02:00
parent 652a14f732
commit 9163ca7d50
5 changed files with 128 additions and 41 deletions

76
blob.go
View File

@ -4,15 +4,13 @@ package git
#include <git2.h>
#include <string.h>
extern int _go_git_blob_create_fromchunks(git_oid *id,
git_repository *repo,
const char *hintpath,
void *payload);
int _go_git_writestream_write(git_writestream *stream, const char *buffer, size_t len);
void _go_git_writestream_free(git_writestream *stream);
*/
import "C"
import (
"io"
"reflect"
"runtime"
"unsafe"
)
@ -78,27 +76,71 @@ func blobChunkCb(buffer *C.char, maxLen C.size_t, handle unsafe.Pointer) int {
return len(goBuf)
}
func (repo *Repository) CreateBlobFromChunks(hintPath string, callback BlobChunkCallback) (*Oid, error) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
func (repo *Repository) CreateFromStream(hintPath string) (*BlobWriteStream, error) {
var chintPath *C.char = nil
var stream *C.git_writestream
if len(hintPath) > 0 {
chintPath = C.CString(hintPath)
defer C.free(unsafe.Pointer(chintPath))
}
oid := C.git_oid{}
payload := &BlobCallbackData{Callback: callback}
handle := pointerHandles.Track(payload)
defer pointerHandles.Untrack(handle)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C._go_git_blob_create_fromchunks(&oid, repo.ptr, chintPath, handle)
if payload.Error != nil {
return nil, payload.Error
}
ecode := C.git_blob_create_fromstream(&stream, repo.ptr, chintPath)
if ecode < 0 {
return nil, MakeGitError(ecode)
}
return newBlobWriteStreamFromC(stream), nil
}
type BlobWriteStream struct {
ptr *C.git_writestream
}
func newBlobWriteStreamFromC(ptr *C.git_writestream) *BlobWriteStream {
stream := &BlobWriteStream{
ptr: ptr,
}
runtime.SetFinalizer(stream, (*BlobWriteStream).Free)
return stream
}
// Implement io.Writer
func (stream *BlobWriteStream) Write(p []byte) (int, error) {
header := (*reflect.SliceHeader)(unsafe.Pointer(&p))
ptr := (*C.char)(unsafe.Pointer(header.Data))
size := C.size_t(header.Len)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C._go_git_writestream_write(stream.ptr, ptr, size)
if ecode < 0 {
return 0, MakeGitError(ecode)
}
return len(p), nil
}
func (stream *BlobWriteStream) Free() {
runtime.SetFinalizer(stream, nil)
C._go_git_writestream_free(stream.ptr)
}
func (stream *BlobWriteStream) Commit() (*Oid, error) {
oid := C.git_oid{}
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_blob_create_fromstream_commit(&oid, stream.ptr)
if ecode < 0 {
return nil, MakeGitError(ecode)
}
return newOidFromC(&oid), nil
}

View File

@ -117,6 +117,30 @@ type FetchOptions struct {
Headers []string
}
type ProxyType uint
const (
// Do not attempt to connect through a proxy
//
// If built against lbicurl, it itself may attempt to connect
// to a proxy if the environment variables specify it.
ProxyTypeNone ProxyType = C.GIT_PROXY_NONE
// Try to auto-detect the proxy from the git configuration.
ProxyTypeAuto ProxyType = C.GIT_PROXY_AUTO
// Connect via the URL given in the options
ProxyTypeSpecified ProxyType = C.GIT_PROXY_SPECIFIED
)
type ProxyOptions struct {
// The type of proxy to use (or none)
Type ProxyType
// The proxy's URL
Url string
}
type Remote struct {
ptr *C.git_remote
callbacks RemoteCallbacks
@ -320,6 +344,20 @@ func pushUpdateReferenceCallback(refname, status *C.char, data unsafe.Pointer) i
return int(callbacks.PushUpdateReferenceCallback(C.GoString(refname), C.GoString(status)))
}
func populateProxyOptions(ptr *C.git_proxy_options, opts *ProxyOptions) {
C.git_proxy_init_options(ptr, C.GIT_PROXY_OPTIONS_VERSION)
if opts == nil {
return
}
ptr._type = C.git_proxy_t(opts.Type)
ptr.url = C.CString(opts.Url)
}
func freeProxyOptions(ptr *C.git_proxy_options) {
C.free(unsafe.Pointer(ptr.url))
}
func RemoteIsValidName(name string) bool {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
@ -654,12 +692,12 @@ func (o *Remote) Fetch(refspecs []string, opts *FetchOptions, msg string) error
return nil
}
func (o *Remote) ConnectFetch(callbacks *RemoteCallbacks, headers []string) error {
return o.Connect(ConnectDirectionFetch, callbacks, headers)
func (o *Remote) ConnectFetch(callbacks *RemoteCallbacks, proxyOpts *ProxyOptions, headers []string) error {
return o.Connect(ConnectDirectionFetch, callbacks, proxyOpts, headers)
}
func (o *Remote) ConnectPush(callbacks *RemoteCallbacks, headers []string) error {
return o.Connect(ConnectDirectionPush, callbacks, headers)
func (o *Remote) ConnectPush(callbacks *RemoteCallbacks, proxyOpts *ProxyOptions, headers []string) error {
return o.Connect(ConnectDirectionPush, callbacks, proxyOpts, headers)
}
// Connect opens a connection to a remote.
@ -669,19 +707,24 @@ func (o *Remote) ConnectPush(callbacks *RemoteCallbacks, headers []string) error
// starts up a specific binary which can only do the one or the other.
//
// 'headers' are extra HTTP headers to use in this connection.
func (o *Remote) Connect(direction ConnectDirection, callbacks *RemoteCallbacks, headers []string) error {
func (o *Remote) Connect(direction ConnectDirection, callbacks *RemoteCallbacks, proxyOpts *ProxyOptions, headers []string) error {
var ccallbacks C.git_remote_callbacks
populateRemoteCallbacks(&ccallbacks, callbacks)
var cproxy C.git_proxy_options
populateProxyOptions(&cproxy, proxyOpts)
defer freeProxyOptions(&cproxy)
cheaders := C.git_strarray{}
cheaders.count = C.size_t(len(headers))
cheaders.strings = makeCStringsFromStrings(headers)
defer freeStrarray(&cheaders)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if ret := C.git_remote_connect(o.ptr, C.git_direction(direction), &ccallbacks, &cheaders); ret != 0 {
if ret := C.git_remote_connect(o.ptr, C.git_direction(direction), &ccallbacks, &cproxy, &cheaders); ret != 0 {
return MakeGitError(ret)
}
return nil

View File

@ -58,7 +58,7 @@ func TestRemoteConnect(t *testing.T) {
remote, err := repo.Remotes.Create("origin", "https://github.com/libgit2/TestGitRepository")
checkFatal(t, err)
err = remote.ConnectFetch(nil, nil)
err = remote.ConnectFetch(nil, nil, nil)
checkFatal(t, err)
}
@ -69,7 +69,7 @@ func TestRemoteLs(t *testing.T) {
remote, err := repo.Remotes.Create("origin", "https://github.com/libgit2/TestGitRepository")
checkFatal(t, err)
err = remote.ConnectFetch(nil, nil)
err = remote.ConnectFetch(nil, nil, nil)
checkFatal(t, err)
heads, err := remote.Ls()
@ -87,7 +87,7 @@ func TestRemoteLsFiltering(t *testing.T) {
remote, err := repo.Remotes.Create("origin", "https://github.com/libgit2/TestGitRepository")
checkFatal(t, err)
err = remote.ConnectFetch(nil, nil)
err = remote.ConnectFetch(nil, nil, nil)
checkFatal(t, err)
heads, err := remote.Ls("master")
@ -166,7 +166,7 @@ func TestRemotePrune(t *testing.T) {
rr, err := repo.Remotes.Lookup("origin")
checkFatal(t, err)
err = rr.ConnectFetch(nil, nil)
err = rr.ConnectFetch(nil, nil, nil)
checkFatal(t, err)
err = rr.Prune(nil)

2
vendor/libgit2 vendored

@ -1 +1 @@
Subproject commit 785d8c48ea8725691da3c50e7dae8751523d4c30
Subproject commit 1dc449105b329ea4f8ea9982bc2da869d231c04a

View File

@ -108,19 +108,6 @@ void _go_git_setup_callbacks(git_remote_callbacks *callbacks) {
callbacks->push_update_reference = (push_update_reference_cb) pushUpdateReferenceCallback;
}
int _go_blob_chunk_cb(char *buffer, size_t maxLen, void *payload)
{
return blobChunkCb(buffer, maxLen, payload);
}
int _go_git_blob_create_fromchunks(git_oid *id,
git_repository *repo,
const char *hintpath,
void *payload)
{
return git_blob_create_fromchunks(id, repo, hintpath, _go_blob_chunk_cb, payload);
}
int _go_git_index_add_all(git_index *index, const git_strarray *pathspec, unsigned int flags, void *callback) {
git_index_matched_path_cb cb = callback ? (git_index_matched_path_cb) &indexMatchedPathCallback : NULL;
return git_index_add_all(index, pathspec, flags, cb, callback);
@ -172,4 +159,19 @@ int _go_git_stash_foreach(git_repository *repo, void *payload) {
return git_stash_foreach(repo, (git_stash_cb)&stashForeachCb, payload);
}
int _go_git_writestream_write(git_writestream *stream, const char *buffer, size_t len)
{
return stream->write(stream, buffer, len);
}
int _go_git_writestream_close(git_writestream *stream)
{
return stream->close(stream);
}
void _go_git_writestream_free(git_writestream *stream)
{
stream->free(stream);
}
/* EOF */