Initial commit
This commit is contained in:
commit
b1d50b70ea
|
@ -0,0 +1,21 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2013 The git2go contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,16 @@
|
|||
git2go
|
||||
======
|
||||
|
||||
Go bindings for [libgit2](http://libgit2.github.com/). Pre-release, things may or may not work. Operator get me Beijing-jing-jing-jing!
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
M to the I to the T.
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
- Carlos Martín (@cmn)
|
||||
- Vicent Martí (@vmg)
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package git
|
||||
|
||||
/*
|
||||
#cgo pkg-config: libgit2
|
||||
#include <git2.h>
|
||||
#include <git2/errors.h>
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Blob struct {
|
||||
ptr *C.git_object
|
||||
}
|
||||
|
||||
func freeBlob(blob *Blob) {
|
||||
C.git_object_free(blob.ptr)
|
||||
}
|
||||
|
||||
func (v *Blob) Contents() []byte {
|
||||
size := C.int(C.git_blob_rawsize(v.ptr))
|
||||
buffer := unsafe.Pointer(C.git_blob_rawcontent(v.ptr))
|
||||
return C.GoBytes(buffer, size)
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package git
|
||||
|
||||
/*
|
||||
#include <git2.h>
|
||||
#include <git2/errors.h>
|
||||
|
||||
extern int _go_git_treewalk(git_tree *tree, git_treewalk_mode mode, void *ptr);
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
)
|
||||
|
||||
// Commit
|
||||
type Commit struct {
|
||||
ptr *C.git_commit
|
||||
}
|
||||
|
||||
func (c *Commit) Id() *Oid {
|
||||
return newOidFromC(C.git_commit_id(c.ptr))
|
||||
}
|
||||
|
||||
func (c *Commit) Message() string {
|
||||
return C.GoString(C.git_commit_message(c.ptr))
|
||||
}
|
||||
|
||||
func (c *Commit) Tree() (*Tree, error) {
|
||||
tree := new(Tree)
|
||||
|
||||
err := C.git_commit_tree(&tree.ptr, c.ptr)
|
||||
if err < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
return tree, nil
|
||||
}
|
||||
|
||||
func (c *Commit) TreeId() *Oid {
|
||||
return newOidFromC(C.git_commit_tree_id(c.ptr))
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
/*
|
||||
func (c *Commit) Author() *Signature {
|
||||
ptr := C.git_commit_author(c.ptr)
|
||||
return &Signature{ptr}
|
||||
}
|
||||
|
||||
func (c *Commit) Committer() *Signature {
|
||||
ptr := C.git_commit_committer(c.ptr)
|
||||
return &Signature{ptr}
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,69 @@
|
|||
package git
|
||||
|
||||
/*
|
||||
#cgo pkg-config: libgit2
|
||||
#include <git2.h>
|
||||
#include <git2/errors.h>
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
ptr *C.git_config
|
||||
}
|
||||
|
||||
func (c *Config) LookupInt32(name string) (v int32, err error) {
|
||||
var out C.int32_t
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
|
||||
ret := C.git_config_get_int32(&out, c.ptr, cname)
|
||||
if ret < 0 {
|
||||
return 0, LastError()
|
||||
}
|
||||
|
||||
return int32(out), nil
|
||||
}
|
||||
|
||||
func (c *Config) LookupInt64(name string) (v int64, err error) {
|
||||
var out C.int64_t
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
|
||||
ret := C.git_config_get_int64(&out, c.ptr, cname)
|
||||
if ret < 0 {
|
||||
return 0, LastError()
|
||||
}
|
||||
|
||||
return int64(out), nil
|
||||
}
|
||||
|
||||
func (c *Config) LookupString(name string) (v string, err error) {
|
||||
var ptr *C.char
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
|
||||
ret := C.git_config_get_string(&ptr, c.ptr, cname)
|
||||
if ret < 0 {
|
||||
return "", LastError()
|
||||
}
|
||||
|
||||
return C.GoString(ptr), nil
|
||||
}
|
||||
|
||||
func (c *Config) Set(name, value string) (err error) {
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
|
||||
cvalue := C.CString(value)
|
||||
defer C.free(unsafe.Pointer(cvalue))
|
||||
|
||||
ret := C.git_config_set_string(c.ptr, cname, cvalue)
|
||||
if ret < 0 {
|
||||
return LastError()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package git
|
||||
|
||||
/*
|
||||
#cgo pkg-config: libgit2
|
||||
#include <git2.h>
|
||||
#include <git2/errors.h>
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
ITEROVER = C.GIT_ITEROVER
|
||||
EEXISTS = C.GIT_EEXISTS
|
||||
ENOTFOUND = C.GIT_ENOTFOUND
|
||||
)
|
||||
|
||||
func init() {
|
||||
C.git_threads_init()
|
||||
}
|
||||
|
||||
// Oid
|
||||
type Oid struct {
|
||||
bytes [20]byte
|
||||
}
|
||||
|
||||
func newOidFromC(coid *C.git_oid) *Oid {
|
||||
oid := new(Oid)
|
||||
copy(oid.bytes[0:20], C.GoBytes(unsafe.Pointer(coid), 20))
|
||||
return oid
|
||||
}
|
||||
|
||||
func NewOid(b []byte) *Oid {
|
||||
oid := new(Oid)
|
||||
copy(oid.bytes[0:20], b[0:20])
|
||||
return oid
|
||||
}
|
||||
|
||||
func (oid *Oid) toC() *C.git_oid {
|
||||
return (*C.git_oid)(unsafe.Pointer(&oid.bytes))
|
||||
}
|
||||
|
||||
func NewOidFromString(s string) (*Oid, error) {
|
||||
o := new(Oid)
|
||||
cs := C.CString(s)
|
||||
defer C.free(unsafe.Pointer(cs))
|
||||
|
||||
if C.git_oid_fromstr(o.toC(), cs) < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func (oid *Oid) String() string {
|
||||
buf := make([]byte, 40)
|
||||
C.git_oid_fmt((*C.char)(unsafe.Pointer(&buf[0])), oid.toC())
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
func (oid *Oid) Bytes() []byte {
|
||||
return oid.bytes[0:]
|
||||
}
|
||||
|
||||
type GitError struct {
|
||||
Message string
|
||||
Code int
|
||||
}
|
||||
|
||||
func (e GitError) Error() string{
|
||||
return e.Message
|
||||
}
|
||||
|
||||
func LastError() error {
|
||||
err := C.giterr_last()
|
||||
return &GitError{C.GoString(err.message), int(err.klass)}
|
||||
}
|
||||
|
||||
func cbool(b bool) C.int {
|
||||
if (b) {
|
||||
return C.int(1)
|
||||
}
|
||||
return C.int(0)
|
||||
}
|
||||
|
||||
func ucbool(b bool) C.uint {
|
||||
if (b) {
|
||||
return C.uint(1)
|
||||
}
|
||||
return C.uint(0)
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package git
|
||||
|
||||
/*
|
||||
#cgo pkg-config: libgit2
|
||||
#include <git2.h>
|
||||
#include <git2/errors.h>
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
"reflect"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
OBJ_ANY = C.GIT_OBJ_ANY
|
||||
OBJ_BAD = C.GIT_OBJ_BAD
|
||||
OBJ_COMMIT = C.GIT_OBJ_COMMIT
|
||||
OBJ_TREE = C.GIT_OBJ_TREE
|
||||
OBJ_BLOB = C.GIT_OBJ_BLOB
|
||||
OBJ_TAG = C.GIT_OBJ_TAG
|
||||
)
|
||||
|
||||
type Odb struct {
|
||||
ptr *C.git_odb
|
||||
}
|
||||
|
||||
func (v *Odb) Exists(oid *Oid) bool {
|
||||
ret := C.git_odb_exists(v.ptr, oid.toC())
|
||||
return ret != 0
|
||||
}
|
||||
|
||||
func (v *Odb) Write(data []byte, otype int) (oid *Oid, err error) {
|
||||
oid = new(Oid)
|
||||
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&data))
|
||||
ret := C.git_odb_write(oid.toC(), v.ptr, unsafe.Pointer(hdr.Data), C.size_t(hdr.Len), C.git_otype(otype))
|
||||
|
||||
if ret < 0 {
|
||||
err = LastError()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (v *Odb) Read(oid *Oid) (obj *OdbObject, err error) {
|
||||
obj = new(OdbObject)
|
||||
ret := C.git_odb_read(&obj.ptr, v.ptr, oid.toC())
|
||||
if ret < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
runtime.SetFinalizer(obj, freeOdbObject)
|
||||
return
|
||||
}
|
||||
|
||||
type OdbObject struct {
|
||||
ptr *C.git_odb_object
|
||||
}
|
||||
|
||||
func freeOdbObject(obj *OdbObject) {
|
||||
C.git_odb_object_free(obj.ptr)
|
||||
}
|
||||
|
||||
func (v *OdbObject) Type() int {
|
||||
return int(C.git_odb_object_type(v.ptr))
|
||||
}
|
||||
|
||||
func (v *OdbObject) Size() int64 {
|
||||
return int64(C.git_odb_object_size(v.ptr))
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
package git
|
||||
|
||||
/*
|
||||
#cgo pkg-config: libgit2
|
||||
#include <git2.h>
|
||||
#include <git2/errors.h>
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Repository
|
||||
type Repository struct {
|
||||
ptr *C.git_repository
|
||||
}
|
||||
|
||||
func Open(path string) (*Repository, error) {
|
||||
repo := new(Repository)
|
||||
|
||||
cpath := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(cpath))
|
||||
|
||||
ret := C.git_repository_open(&repo.ptr, cpath)
|
||||
if ret < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
runtime.SetFinalizer(repo, freeRepository)
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
func Init(path string, isbare bool) (*Repository, error) {
|
||||
repo := new(Repository)
|
||||
|
||||
cpath := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(cpath))
|
||||
|
||||
ret := C.git_repository_init(&repo.ptr, cpath, ucbool(isbare))
|
||||
if ret < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
runtime.SetFinalizer(repo, freeRepository)
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
func freeRepository(repo *Repository) {
|
||||
C.git_repository_free(repo.ptr)
|
||||
}
|
||||
|
||||
func (v *Repository) Config() (*Config, error) {
|
||||
config := new(Config)
|
||||
|
||||
ret := C.git_repository_config(&config.ptr, v.ptr)
|
||||
if ret < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func (v *Repository) LookupTree(oid *Oid) (*Tree, error) {
|
||||
tree := new(Tree)
|
||||
ret := C.git_tree_lookup(&tree.ptr, v.ptr, oid.toC())
|
||||
if ret < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
return tree, nil
|
||||
}
|
||||
|
||||
func (v *Repository) LookupCommit(o *Oid) (*Commit, error) {
|
||||
commit := new(Commit)
|
||||
ecode := C.git_commit_lookup(&commit.ptr, v.ptr, o.toC())
|
||||
if ecode < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
return commit, nil
|
||||
}
|
||||
|
||||
/* TODO
|
||||
func (v *Repository) Commit(
|
||||
refname string, author, committer *Signature,
|
||||
message string, tree *Tree, parents ...*Commit) (*Oid, error) {
|
||||
|
||||
oid := new(Oid)
|
||||
cref := C.CString(refname)
|
||||
defer C.free(unsafe.Pointer(cref))
|
||||
cmsg := C.CString(message)
|
||||
defer C.free(unsafe.Pointer(cmsg))
|
||||
nparents := len(parents)
|
||||
var cparents []*C.git_commit = nil
|
||||
var parentsarg **C.git_commit = nil
|
||||
if nparents > 0 {
|
||||
cparents = make([]*C.git_commit, nparents)
|
||||
for i, v := range parents {
|
||||
cparents[i] = v.ptr
|
||||
}
|
||||
parentsarg = &cparents[0]
|
||||
}
|
||||
|
||||
ret := C.git_commit_create(
|
||||
oid.toC(), v.ptr, cref,
|
||||
author.git_signature, committer.git_signature,
|
||||
nil, cmsg, tree.ptr, C.int(nparents), parentsarg)
|
||||
|
||||
if ret < GIT_SUCCESS {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
return oid, nil
|
||||
}
|
||||
*/
|
||||
|
||||
func freeOdb(odb *Odb) {
|
||||
C.git_odb_free(odb.ptr)
|
||||
}
|
||||
|
||||
func (v *Repository) Odb() (odb *Odb, err error) {
|
||||
odb = new(Odb)
|
||||
if ret := C.git_repository_odb(&odb.ptr, v.ptr); ret < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
runtime.SetFinalizer(odb, freeOdb)
|
||||
return
|
||||
}
|
||||
|
||||
func (v *Repository) TreeBuilder() (*TreeBuilder, error) {
|
||||
bld := new(TreeBuilder)
|
||||
if ret := C.git_treebuilder_create(&bld.ptr, nil); ret < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
bld.repo = v
|
||||
return bld, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
package git
|
||||
|
||||
/*
|
||||
#include <git2.h>
|
||||
#include <git2/errors.h>
|
||||
|
||||
extern int _go_git_treewalk(git_tree *tree, git_treewalk_mode mode, void *ptr);
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Tree struct {
|
||||
ptr *C.git_tree
|
||||
}
|
||||
|
||||
type TreeEntry struct {
|
||||
Name string
|
||||
Oid *Oid
|
||||
Type int
|
||||
}
|
||||
|
||||
func newTreeEntry(entry *C.git_tree_entry) *TreeEntry {
|
||||
return &TreeEntry{
|
||||
C.GoString(C.git_tree_entry_name(entry)),
|
||||
newOidFromC(C.git_tree_entry_id(entry)),
|
||||
int(C.git_tree_entry_type(entry)),
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tree) Free() {
|
||||
C.git_tree_free(t.ptr)
|
||||
}
|
||||
|
||||
func TreeLookup(repo *Repository, oid *Oid) (*Tree, error) {
|
||||
tree := new(Tree)
|
||||
err := C.git_tree_lookup(&tree.ptr, repo.ptr, oid.toC())
|
||||
if err < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
return tree, nil
|
||||
}
|
||||
|
||||
func (t *Tree) EntryByName(filename string) *TreeEntry {
|
||||
cname := C.CString(filename)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
|
||||
entry := C.git_tree_entry_byname(t.ptr, cname)
|
||||
if entry == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return newTreeEntry(entry)
|
||||
}
|
||||
|
||||
func (t *Tree) EntryByIndex(index uint64) *TreeEntry {
|
||||
entry := C.git_tree_entry_byindex(t.ptr, C.size_t(index))
|
||||
if entry == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return newTreeEntry(entry)
|
||||
}
|
||||
|
||||
func (t *Tree) EntryCount() uint64 {
|
||||
num := C.git_tree_entrycount(t.ptr)
|
||||
return uint64(num)
|
||||
}
|
||||
|
||||
type TreeWalkCallback func(string, *TreeEntry) int
|
||||
|
||||
//export CallbackGitTreeWalk
|
||||
func CallbackGitTreeWalk(_root unsafe.Pointer, _entry unsafe.Pointer, ptr unsafe.Pointer) C.int {
|
||||
root := C.GoString((*C.char)(_root))
|
||||
entry := (*C.git_tree_entry)(_entry)
|
||||
callback := *(*TreeWalkCallback)(ptr)
|
||||
|
||||
return C.int(callback(root, newTreeEntry(entry)))
|
||||
}
|
||||
|
||||
func (t *Tree) Walk(callback TreeWalkCallback) error {
|
||||
err := C._go_git_treewalk(
|
||||
t.ptr,
|
||||
C.GIT_TREEWALK_PRE,
|
||||
unsafe.Pointer(&callback),
|
||||
)
|
||||
|
||||
if err < 0 {
|
||||
return LastError()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type TreeBuilder struct {
|
||||
ptr *C.git_treebuilder
|
||||
repo *Repository
|
||||
}
|
||||
|
||||
func freeTreeBuilder(v *TreeBuilder) {
|
||||
C.git_treebuilder_free(v.ptr)
|
||||
}
|
||||
|
||||
func (v *TreeBuilder) Insert(filename string, id *Oid, filemode int) (error) {
|
||||
cfilename := C.CString(filename)
|
||||
defer C.free(unsafe.Pointer(cfilename))
|
||||
|
||||
err := C.git_treebuilder_insert(nil, v.ptr, cfilename, id.toC(), C.git_filemode_t(filemode))
|
||||
if err < 0 {
|
||||
return LastError()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *TreeBuilder) Write() (*Oid, error) {
|
||||
oid := new(Oid)
|
||||
err := C.git_treebuilder_write(oid.toC(), v.repo.ptr, v.ptr)
|
||||
|
||||
if err < 0 {
|
||||
return nil, LastError()
|
||||
}
|
||||
|
||||
return oid, nil
|
||||
}
|
Loading…
Reference in New Issue