From ee7e153ff8e5c5698924dbf3b8907777b42da051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Fri, 20 Sep 2013 22:03:15 +0200 Subject: [PATCH] more --- git.go | 4 ++++ remote.go | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ remote_test.go | 37 +++++++++++++++++++++++++++++ repository.go | 3 +++ wrapper.c | 16 +++++++++++++ 5 files changed, 123 insertions(+) create mode 100644 remote_test.go diff --git a/git.go b/git.go index 6f81293..ea4f9d2 100644 --- a/git.go +++ b/git.go @@ -42,6 +42,10 @@ func newOidFromC(coid *C.git_oid) *Oid { return oid } +func CopyOid(oid *Oid, coid *C.git_oid) { + copy(oid.bytes[0:20], C.GoBytes(unsafe.Pointer(coid), 20)) +} + func NewOid(b []byte) *Oid { oid := new(Oid) copy(oid.bytes[0:20], b[0:20]) diff --git a/remote.go b/remote.go index 291a3b7..d160f3e 100644 --- a/remote.go +++ b/remote.go @@ -4,6 +4,8 @@ package git #cgo pkg-config: libgit2 #include #include + +extern int _go_git_remote_ls(git_remote *remote, void *payload); */ import "C" import ( @@ -33,6 +35,9 @@ type Remote struct { } func (r *Remote) Connect(direction RemoteDirection) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_remote_connect(r.ptr, C.git_direction(direction)) if ret < 0 { return LastError() @@ -62,6 +67,9 @@ func (r *Remote) Stop() { } func (r *Remote) Save() error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_remote_save(r.ptr) if ret < 0 { return LastError() @@ -70,6 +78,40 @@ func (r *Remote) Save() error { return nil } +func (r *Remote) Ls() ([]*RemoteHead, error) { + var data headlistData + + ret := C._go_git_remote_ls(r.ptr, unsafe.Pointer(&data)) + if ret < 0 { + return nil, LastError() + } + + return data.slice, nil +} + +func (r *Remote) Download (error) { + ret := C.git_remote_download(r.ptr) + if ret < 0 { + LastError() + } + + return nil +} + +type headlistData struct { + slice []*RemoteHead +} + +//export remoteHeadlistCb +func remoteHeadlistCb(rhead *C.git_remote_head, dataptr unsafe.Pointer) int { + data := (*headlistData)(dataptr) + + head := newRemoteHeadFromC(rhead) + data.slice = append(data.slice, head) + + return 0 +} + func (r *Remote) Free() { runtime.SetFinalizer(r, nil) C.git_remote_free(r.ptr) @@ -87,6 +129,27 @@ func newRemoteFromC(ptr *C.git_remote) *Remote { return remote } +// remote heads + +// RemoteHead represents a reference available in the remote repository. +type RemoteHead struct { + Local bool + Oid Oid + Loid Oid + Name string +} + +func newRemoteHeadFromC(ptr *C.git_remote_head) *RemoteHead { + head := &RemoteHead { + Local: ptr.local != 0, + Name: C.GoString(ptr.name), + } + + CopyOid(&head.Oid, &ptr.oid) + CopyOid(&head.Loid, &ptr.loid) + + return head +} // These belong to the git_remote namespace but don't require any remote diff --git a/remote_test.go b/remote_test.go new file mode 100644 index 0000000..298f4cd --- /dev/null +++ b/remote_test.go @@ -0,0 +1,37 @@ +package git + +import ( + "testing" +) + +func TestRemoteLs(t *testing.T) { + repo := createTestRepo(t) + remote, err := repo.CreateRemote("origin", "git://github.com/libgit2/TestGitRepository") + checkFatal(t, err) + + err = remote.Connect(RemoteDirectionFetch) + checkFatal(t, err) + + if remote.IsConnected() != true { + t.Fatal("Connected but not connected") + } + + expected := []string{ + "HEAD", + "refs/heads/first-merge", + "refs/heads/master", + "refs/heads/no-parent", + "refs/tags/annotated_tag", + "refs/tags/annotated_tag^{}", + "refs/tags/blob", + "refs/tags/commit_tree", + "refs/tags/nearly-dangling", + } + + refs, err := remote.Ls() + for i, s := range expected { + if refs[i].Name != s { + t.Fatal("remote refs not as expected") + } + } +} \ No newline at end of file diff --git a/repository.go b/repository.go index d6b52ef..c2b3c24 100644 --- a/repository.go +++ b/repository.go @@ -126,6 +126,9 @@ func (v *Repository) LookupReference(name string) (*Reference, error) { } func (v *Repository) LookupRemote(name string) (*Remote, error) { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) diff --git a/wrapper.c b/wrapper.c index 2af3974..40ca383 100644 --- a/wrapper.c +++ b/wrapper.c @@ -24,4 +24,20 @@ int _go_git_odb_foreach(git_odb *db, void *payload) { return git_odb_foreach(db, (git_odb_foreach_cb)&odbForEachCb, payload); } + +int _go_git_remote_ls(git_remote *remote, void *payload) +{ + return git_remote_ls(remote, (git_headlist_cb) remoteHeadlistCb, payload); +} + /* EOF */ + + + + + + + + + +