From 140f362428d07ba130c4797b346e1bc2b8777b78 Mon Sep 17 00:00:00 2001 From: Axel Wagner Date: Thu, 16 May 2013 13:56:07 +0200 Subject: [PATCH 1/3] Add support for git_packbuilder --- packbuilder.go | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++ wrapper.c | 6 +++ 2 files changed, 105 insertions(+) create mode 100644 packbuilder.go diff --git a/packbuilder.go b/packbuilder.go new file mode 100644 index 0000000..40b2c81 --- /dev/null +++ b/packbuilder.go @@ -0,0 +1,99 @@ +package git + +/* +#cgo pkg-config: libgit2 +#include +#include +#include +#include + +extern int _go_git_packbuilder_foreach(git_packbuilder *pb, void *payload); +*/ +import "C" +import ( + "runtime" + "unsafe" +) + +type Packbuilder struct { + ptr *C.git_packbuilder +} + +func (repo *Repository) NewPackbuilder() (*Packbuilder, error) { + builder := &Packbuilder{} + ret := C.git_packbuilder_new(&builder.ptr, repo.ptr) + if ret != 0 { + return nil, LastError() + } + runtime.SetFinalizer(builder, (*Packbuilder).Free) + return builder, nil +} + +func (pb *Packbuilder) Free() { + runtime.SetFinalizer(pb, nil) + C.git_packbuilder_free(pb.ptr) +} + +func (pb *Packbuilder) Insert(id *Oid, name string) error { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + ret := C.git_packbuilder_insert(pb.ptr, id.toC(), cname) + if ret != 0 { + return LastError() + } + return nil +} + +func (pb *Packbuilder) InsertCommit(id *Oid) error { + ret := C.git_packbuilder_insert_commit(pb.ptr, id.toC()) + if ret != 0 { + return LastError() + } + return nil +} + +func (pb *Packbuilder) InsertTree(id *Oid) error { + ret := C.git_packbuilder_insert_tree(pb.ptr, id.toC()) + if ret != 0 { + return LastError() + } + return nil +} + +func (pb *Packbuilder) ObjectCount() uint32 { + return uint32(C.git_packbuilder_object_count(pb.ptr)) +} + +func (pb *Packbuilder) WriteToFile(name string) error { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + ret := C.git_packbuilder_write(pb.ptr, cname) + if ret != 0 { + return LastError() + } + return nil +} + +func (pb *Packbuilder) Written() uint32 { + return uint32(C.git_packbuilder_written(pb.ptr)) +} + +//export packbuilderForEachCb +func packbuilderForEachCb(buf unsafe.Pointer, size C.size_t, payload unsafe.Pointer) int { + ch := *(*chan []byte)(payload) + + slice := C.GoBytes(buf, C.int(size)) + ch <- slice + return 0 +} + +func (pb *Packbuilder) forEachWrap(ch chan []byte) { + C._go_git_packbuilder_foreach(pb.ptr, unsafe.Pointer(&ch)) + close(ch) +} + +func (pb *Packbuilder) ForEach() chan []byte { + ch := make(chan []byte, 0) + go pb.forEachWrap(ch) + return ch +} diff --git a/wrapper.c b/wrapper.c index 13478cb..67f34fd 100644 --- a/wrapper.c +++ b/wrapper.c @@ -1,6 +1,7 @@ #include "_cgo_export.h" #include "git2.h" #include "git2/submodule.h" +#include "git2/pack.h" typedef int (*gogit_submodule_cbk)(git_submodule *sm, const char *name, void *payload); @@ -14,4 +15,9 @@ int _go_git_treewalk(git_tree *tree, git_treewalk_mode mode, void *ptr) return git_tree_walk(tree, mode, (git_treewalk_cb)&CallbackGitTreeWalk, ptr); } +int _go_git_packbuilder_foreach(git_packbuilder *pb, void *payload) +{ + return git_packbuilder_foreach(pb, (git_packbuilder_foreach_cb)&packbuilderForEachCb, payload); +} + /* EOF */ From 1da989e28b04807fb9781c3198769630ccb9a0fd Mon Sep 17 00:00:00 2001 From: Axel Wagner Date: Thu, 16 May 2013 14:02:22 +0200 Subject: [PATCH 2/3] Add Write(w io.Writer) to packbuilder This wraps (*packbuilder).ForEach(), making it possible to write the pack easiliy to a tcp-connection, a HTTP-Body or the like. --- packbuilder.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packbuilder.go b/packbuilder.go index 40b2c81..6228e12 100644 --- a/packbuilder.go +++ b/packbuilder.go @@ -74,6 +74,17 @@ func (pb *Packbuilder) WriteToFile(name string) error { return nil } +func (pb *Packbuilder) Write(w io.Writer) error { + ch := pb.Foreach() + for _, slice := range ch { + _, err := w.Write(slice) + if err != nil { + return err + } + } + return nil +} + func (pb *Packbuilder) Written() uint32 { return uint32(C.git_packbuilder_written(pb.ptr)) } From 3a1bbbdf9dcdf88c909ea9df127f32b126d38547 Mon Sep 17 00:00:00 2001 From: Axel Wagner Date: Thu, 16 May 2013 16:53:21 +0200 Subject: [PATCH 3/3] Correct some errors from 1da989e --- packbuilder.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packbuilder.go b/packbuilder.go index 6228e12..8cc03bd 100644 --- a/packbuilder.go +++ b/packbuilder.go @@ -13,6 +13,7 @@ import "C" import ( "runtime" "unsafe" + "io" ) type Packbuilder struct { @@ -75,8 +76,8 @@ func (pb *Packbuilder) WriteToFile(name string) error { } func (pb *Packbuilder) Write(w io.Writer) error { - ch := pb.Foreach() - for _, slice := range ch { + ch := pb.ForEach() + for slice := range ch { _, err := w.Write(slice) if err != nil { return err