Compare commits

...

2 Commits

Author SHA1 Message Date
Carlos Martín Nieto f13b40445e Remote: reorg push 2014-05-09 23:32:09 +02:00
Carlos Martín Nieto 84ce8645de Remote: specify the refspecs and callbacks in Fetch
The Remote interface mixes the configuration of a remote with overriding
the configuration for a paritcular operation. This makes the remotes
trickier to use than they should be.

Move towards letting the user specify the refspecs and callbacks they
want for a particular Fetch() operation intsead of setting it for a
Remote object that they then need to throw away.
2014-05-09 22:51:58 +02:00
2 changed files with 98 additions and 5 deletions

1
git.go
View File

@ -91,6 +91,7 @@ const (
var ( var (
ErrInvalid = errors.New("Invalid state for operation") ErrInvalid = errors.New("Invalid state for operation")
ErrPushUnpack = errors.New("Error unpacking on the remote end")
) )
func init() { func init() {

102
remote.go
View File

@ -2,9 +2,10 @@ package git
/* /*
#include <git2.h> #include <git2.h>
#include <git2/errors.h>
extern void _go_git_setup_callbacks(git_remote_callbacks *callbacks); extern void _go_git_setup_callbacks(git_remote_callbacks *callbacks);
int _go_git_push_status_foreach(git_push *push, void *data);
int _go_git_push_set_callbacks(git_push *push, void *packbuilder_progress_data, void *transfer_progress_data);
*/ */
import "C" import "C"
@ -409,7 +410,7 @@ func (o *Remote) PushRefspecs() ([]string, error) {
return refspecs, nil return refspecs, nil
} }
func (o *Remote) SetPushRefspecs(refspecs []string) error { func setPushRefspecs(remote *C.git_remote, refspecs []string) error {
crefspecs := C.git_strarray{} crefspecs := C.git_strarray{}
crefspecs.count = C.size_t(len(refspecs)) crefspecs.count = C.size_t(len(refspecs))
crefspecs.strings = makeCStringsFromStrings(refspecs) crefspecs.strings = makeCStringsFromStrings(refspecs)
@ -418,13 +419,17 @@ func (o *Remote) SetPushRefspecs(refspecs []string) error {
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
ret := C.git_remote_set_push_refspecs(o.ptr, &crefspecs) ret := C.git_remote_set_push_refspecs(remote, &crefspecs)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
return nil return nil
} }
func (o *Remote) SetPushRefspecs(refspecs []string) error {
return setPushRefspecs(o.ptr, refspecs)
}
func (o *Remote) ClearRefspecs() { func (o *Remote) ClearRefspecs() {
C.git_remote_clear_refspecs(o.ptr) C.git_remote_clear_refspecs(o.ptr)
} }
@ -433,7 +438,24 @@ func (o *Remote) RefspecCount() uint {
return uint(C.git_remote_refspec_count(o.ptr)) return uint(C.git_remote_refspec_count(o.ptr))
} }
func (o *Remote) Fetch(sig *Signature, msg string) error { func (o *Remote) Fetch(refspecs []string, callbacks *RemoteCallbacks, sig *Signature, msg string) error {
var remote *C.git_remote
if ret := C.git_remote_dup(&remote, o.ptr); ret < 0 {
return MakeGitError(ret)
}
defer C.git_remote_free(remote)
var ccallbacks C.git_remote_callbacks
populateRemoteCallbacks(&ccallbacks, callbacks)
C.git_remote_set_callbacks(remote, &ccallbacks)
if refspecs != nil {
err := setPushRefspecs(remote, refspecs)
if err != nil {
return err
}
}
var csig *C.git_signature = nil var csig *C.git_signature = nil
if sig != nil { if sig != nil {
@ -448,9 +470,79 @@ func (o *Remote) Fetch(sig *Signature, msg string) error {
cmsg = C.CString(msg) cmsg = C.CString(msg)
defer C.free(unsafe.Pointer(cmsg)) defer C.free(unsafe.Pointer(cmsg))
} }
ret := C.git_remote_fetch(o.ptr, csig, cmsg)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_remote_fetch(remote, csig, cmsg)
if ret < 0 { if ret < 0 {
return MakeGitError(ret) return MakeGitError(ret)
} }
return nil return nil
} }
func (o *Remote) Push(refspecs []string, callbacks *PushCallbacks, opts PushOptions, statusForeach StatusForeachFunc, sig *Signature, msg string) error {
var remote *C.git_remote
if ret := C.git_remote_dup(&remote, o.ptr); ret < 0 {
return MakeGitError(ret)
}
var push *C.git_push
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if ret := C.git_push_new(&push, o.ptr); ret < 0 {
return MakeGitError(ret)
}
defer C.git_push_free(push)
for _, str := range refspecs {
cstr := C.CString(str)
defer C.free(unsafe.Pointer(cstr))
if ret := C.git_push_add_refspec(push, cstr); ret < 0 {
return MakeGitError(ret)
}
}
copts := C.git_push_options{
version: C.uint(opts.Version),
pb_parallelism: C.uint(opts.PbParallelism),
}
if ret := C.git_push_set_options(push, &copts); ret < 0 {
return MakeGitError(ret)
}
if ret := C.git_push_finish(push); ret < 0 {
return MakeGitError(ret)
}
if C.git_push_unpack_ok(push) == 0 {
return ErrPushUnpack
}
if ret := C._go_git_push_status_foreach(push, unsafe.Pointer(&statusForeach)); ret < 0 {
return MakeGitError(ret)
}
var csig *C.git_signature = nil
if sig != nil {
csig = sig.toC()
defer C.free(unsafe.Pointer(csig))
}
var cmsg *C.char
if msg == "" {
cmsg = nil
} else {
cmsg = C.CString(msg)
defer C.free(unsafe.Pointer(cmsg))
}
if ret := C.git_push_update_tips(push, csig, cmsg); ret < 0 {
return MakeGitError(ret)
}
return nil
}