2013-03-05 13:53:04 -06:00
|
|
|
package git
|
|
|
|
|
|
|
|
/*
|
|
|
|
#include <git2.h>
|
|
|
|
#include <git2/errors.h>
|
|
|
|
*/
|
|
|
|
import "C"
|
|
|
|
import (
|
|
|
|
"runtime"
|
2013-11-14 05:08:34 -06:00
|
|
|
"unsafe"
|
2013-03-05 13:53:04 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
// Repository
|
|
|
|
type Repository struct {
|
|
|
|
ptr *C.git_repository
|
|
|
|
}
|
|
|
|
|
2013-03-06 10:18:25 -06:00
|
|
|
func OpenRepository(path string) (*Repository, error) {
|
2013-03-05 13:53:04 -06:00
|
|
|
repo := new(Repository)
|
|
|
|
|
|
|
|
cpath := C.CString(path)
|
|
|
|
defer C.free(unsafe.Pointer(cpath))
|
|
|
|
|
2013-09-18 02:23:47 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
ret := C.git_repository_open(&repo.ptr, cpath)
|
|
|
|
if ret < 0 {
|
|
|
|
return nil, LastError()
|
|
|
|
}
|
|
|
|
|
2013-03-05 18:43:48 -06:00
|
|
|
runtime.SetFinalizer(repo, (*Repository).Free)
|
2013-03-05 13:53:04 -06:00
|
|
|
return repo, nil
|
|
|
|
}
|
|
|
|
|
2013-03-06 10:18:25 -06:00
|
|
|
func InitRepository(path string, isbare bool) (*Repository, error) {
|
2013-03-05 13:53:04 -06:00
|
|
|
repo := new(Repository)
|
|
|
|
|
|
|
|
cpath := C.CString(path)
|
|
|
|
defer C.free(unsafe.Pointer(cpath))
|
|
|
|
|
2013-09-18 02:23:47 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
ret := C.git_repository_init(&repo.ptr, cpath, ucbool(isbare))
|
|
|
|
if ret < 0 {
|
|
|
|
return nil, LastError()
|
|
|
|
}
|
|
|
|
|
2013-03-05 18:43:48 -06:00
|
|
|
runtime.SetFinalizer(repo, (*Repository).Free)
|
2013-03-05 13:53:04 -06:00
|
|
|
return repo, nil
|
|
|
|
}
|
|
|
|
|
2013-12-19 16:24:44 -06:00
|
|
|
func NewRepositoryWrapOdb(odb *Odb) (repo *Repository, err error) {
|
2013-12-18 23:33:23 -06:00
|
|
|
repo = new(Repository)
|
2013-12-17 17:46:25 -06:00
|
|
|
|
2013-12-18 23:33:23 -06:00
|
|
|
ret := C.git_repository_wrap_odb(&repo.ptr, odb.ptr)
|
|
|
|
if ret < 0 {
|
|
|
|
return nil, LastError()
|
2013-12-18 16:25:54 -06:00
|
|
|
}
|
|
|
|
|
2013-12-18 23:33:23 -06:00
|
|
|
runtime.SetFinalizer(repo, (*Repository).Free)
|
|
|
|
return
|
2013-12-17 17:46:25 -06:00
|
|
|
}
|
|
|
|
|
2013-03-05 18:43:48 -06:00
|
|
|
func (v *Repository) Free() {
|
|
|
|
runtime.SetFinalizer(v, nil)
|
|
|
|
C.git_repository_free(v.ptr)
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Repository) Config() (*Config, error) {
|
|
|
|
config := new(Config)
|
|
|
|
|
2013-09-18 02:23:47 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
ret := C.git_repository_config(&config.ptr, v.ptr)
|
|
|
|
if ret < 0 {
|
|
|
|
return nil, LastError()
|
|
|
|
}
|
|
|
|
|
2013-11-14 07:24:43 -06:00
|
|
|
runtime.SetFinalizer(config, (*Config).Free)
|
2013-03-05 13:53:04 -06:00
|
|
|
return config, nil
|
|
|
|
}
|
|
|
|
|
2013-03-06 06:10:53 -06:00
|
|
|
func (v *Repository) Index() (*Index, error) {
|
|
|
|
var ptr *C.git_index
|
2013-09-18 02:23:47 -05:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-03-06 06:10:53 -06:00
|
|
|
ret := C.git_repository_index(&ptr, v.ptr)
|
|
|
|
if ret < 0 {
|
|
|
|
return nil, LastError()
|
|
|
|
}
|
|
|
|
|
|
|
|
return newIndexFromC(ptr), nil
|
|
|
|
}
|
|
|
|
|
2013-04-16 16:18:35 -05:00
|
|
|
func (v *Repository) lookupType(oid *Oid, t ObjectType) (Object, error) {
|
2013-04-16 16:04:35 -05:00
|
|
|
var ptr *C.git_object
|
2013-09-18 02:23:47 -05:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-04-16 16:04:35 -05:00
|
|
|
ret := C.git_object_lookup(&ptr, v.ptr, oid.toC(), C.git_otype(t))
|
2013-03-05 13:53:04 -06:00
|
|
|
if ret < 0 {
|
|
|
|
return nil, LastError()
|
|
|
|
}
|
|
|
|
|
2013-04-16 16:04:35 -05:00
|
|
|
return allocObject(ptr), nil
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
2013-04-16 16:18:35 -05:00
|
|
|
func (v *Repository) Lookup(oid *Oid) (Object, error) {
|
2013-09-12 03:40:57 -05:00
|
|
|
return v.lookupType(oid, ObjectAny)
|
2013-04-16 16:18:35 -05:00
|
|
|
}
|
|
|
|
|
2013-04-16 16:04:35 -05:00
|
|
|
func (v *Repository) LookupTree(oid *Oid) (*Tree, error) {
|
2013-09-12 03:40:57 -05:00
|
|
|
obj, err := v.lookupType(oid, ObjectTree)
|
2013-04-16 16:04:35 -05:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
2013-04-16 16:04:35 -05:00
|
|
|
return obj.(*Tree), nil
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
2013-04-16 16:04:35 -05:00
|
|
|
func (v *Repository) LookupCommit(oid *Oid) (*Commit, error) {
|
2013-09-12 03:40:57 -05:00
|
|
|
obj, err := v.lookupType(oid, ObjectCommit)
|
2013-04-16 16:04:35 -05:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return obj.(*Commit), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Repository) LookupBlob(oid *Oid) (*Blob, error) {
|
2013-09-12 03:40:57 -05:00
|
|
|
obj, err := v.lookupType(oid, ObjectBlob)
|
2013-04-16 16:04:35 -05:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2013-03-06 16:59:33 -06:00
|
|
|
}
|
|
|
|
|
2013-04-16 16:04:35 -05:00
|
|
|
return obj.(*Blob), nil
|
2013-03-06 16:59:33 -06:00
|
|
|
}
|
|
|
|
|
2013-03-06 11:29:43 -06:00
|
|
|
func (v *Repository) LookupReference(name string) (*Reference, error) {
|
|
|
|
cname := C.CString(name)
|
|
|
|
defer C.free(unsafe.Pointer(cname))
|
|
|
|
var ptr *C.git_reference
|
|
|
|
|
2013-09-18 02:23:47 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-03-06 11:29:43 -06:00
|
|
|
ecode := C.git_reference_lookup(&ptr, v.ptr, cname)
|
|
|
|
if ecode < 0 {
|
|
|
|
return nil, LastError()
|
|
|
|
}
|
|
|
|
|
|
|
|
return newReferenceFromC(ptr), nil
|
|
|
|
}
|
|
|
|
|
2014-01-29 17:01:26 -06:00
|
|
|
func (v *Repository) CreateReference(name string, oid *Oid, force bool, sig *Signature, msg string) (*Reference, error) {
|
2013-03-06 11:29:43 -06:00
|
|
|
cname := C.CString(name)
|
|
|
|
defer C.free(unsafe.Pointer(cname))
|
2014-01-29 17:01:26 -06:00
|
|
|
|
|
|
|
csig := sig.toC()
|
|
|
|
defer C.free(unsafe.Pointer(csig))
|
|
|
|
|
|
|
|
cmsg := C.CString(msg)
|
|
|
|
defer C.free(unsafe.Pointer(cmsg))
|
|
|
|
|
2013-03-06 11:29:43 -06:00
|
|
|
var ptr *C.git_reference
|
|
|
|
|
2014-01-29 17:01:26 -06:00
|
|
|
ecode := C.git_reference_create(&ptr, v.ptr, cname, oid.toC(), cbool(force), csig, cmsg)
|
2013-09-18 02:23:47 -05:00
|
|
|
|
2013-03-06 11:29:43 -06:00
|
|
|
if ecode < 0 {
|
|
|
|
return nil, LastError()
|
|
|
|
}
|
|
|
|
|
|
|
|
return newReferenceFromC(ptr), nil
|
|
|
|
}
|
|
|
|
|
2014-01-29 17:01:26 -06:00
|
|
|
func (v *Repository) CreateSymbolicReference(name, target string, force bool, sig *Signature, msg string) (*Reference, error) {
|
2013-03-06 11:29:43 -06:00
|
|
|
cname := C.CString(name)
|
|
|
|
defer C.free(unsafe.Pointer(cname))
|
2014-01-29 17:01:26 -06:00
|
|
|
|
2013-03-06 11:29:43 -06:00
|
|
|
ctarget := C.CString(target)
|
|
|
|
defer C.free(unsafe.Pointer(ctarget))
|
2014-01-29 17:01:26 -06:00
|
|
|
|
|
|
|
csig := sig.toC()
|
|
|
|
defer C.free(unsafe.Pointer(csig))
|
|
|
|
|
|
|
|
cmsg := C.CString(msg)
|
|
|
|
defer C.free(unsafe.Pointer(cmsg))
|
|
|
|
|
2013-03-06 11:29:43 -06:00
|
|
|
var ptr *C.git_reference
|
|
|
|
|
2014-01-29 17:01:26 -06:00
|
|
|
ecode := C.git_reference_symbolic_create(&ptr, v.ptr, cname, ctarget, cbool(force), csig, cmsg)
|
2013-09-18 02:23:47 -05:00
|
|
|
|
2013-03-06 11:29:43 -06:00
|
|
|
if ecode < 0 {
|
|
|
|
return nil, LastError()
|
|
|
|
}
|
|
|
|
|
|
|
|
return newReferenceFromC(ptr), nil
|
|
|
|
}
|
|
|
|
|
2013-03-05 14:47:55 -06:00
|
|
|
func (v *Repository) Walk() (*RevWalk, error) {
|
|
|
|
walk := new(RevWalk)
|
2013-09-18 02:23:47 -05:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-03-05 14:47:55 -06:00
|
|
|
ecode := C.git_revwalk_new(&walk.ptr, v.ptr)
|
|
|
|
if ecode < 0 {
|
|
|
|
return nil, LastError()
|
|
|
|
}
|
|
|
|
|
|
|
|
walk.repo = v
|
|
|
|
runtime.SetFinalizer(walk, freeRevWalk)
|
|
|
|
return walk, nil
|
|
|
|
}
|
|
|
|
|
2013-03-06 09:59:45 -06:00
|
|
|
func (v *Repository) CreateCommit(
|
2013-03-05 13:53:04 -06:00
|
|
|
refname string, author, committer *Signature,
|
|
|
|
message string, tree *Tree, parents ...*Commit) (*Oid, error) {
|
|
|
|
|
|
|
|
oid := new(Oid)
|
2013-03-06 09:59:45 -06:00
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
cref := C.CString(refname)
|
|
|
|
defer C.free(unsafe.Pointer(cref))
|
2013-03-06 09:59:45 -06:00
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
cmsg := C.CString(message)
|
|
|
|
defer C.free(unsafe.Pointer(cmsg))
|
2013-03-06 09:59:45 -06:00
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
var cparents []*C.git_commit = nil
|
|
|
|
var parentsarg **C.git_commit = nil
|
2013-03-06 09:59:45 -06:00
|
|
|
|
2013-11-14 05:08:34 -06:00
|
|
|
nparents := len(parents)
|
2013-03-05 13:53:04 -06:00
|
|
|
if nparents > 0 {
|
|
|
|
cparents = make([]*C.git_commit, nparents)
|
|
|
|
for i, v := range parents {
|
|
|
|
cparents[i] = v.ptr
|
|
|
|
}
|
|
|
|
parentsarg = &cparents[0]
|
|
|
|
}
|
|
|
|
|
2013-03-06 09:59:45 -06:00
|
|
|
authorSig := author.toC()
|
|
|
|
defer C.git_signature_free(authorSig)
|
|
|
|
|
|
|
|
committerSig := committer.toC()
|
|
|
|
defer C.git_signature_free(committerSig)
|
|
|
|
|
2013-09-18 02:23:47 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
ret := C.git_commit_create(
|
|
|
|
oid.toC(), v.ptr, cref,
|
2013-03-06 09:59:45 -06:00
|
|
|
authorSig, committerSig,
|
2013-03-05 13:53:04 -06:00
|
|
|
nil, cmsg, tree.ptr, C.int(nparents), parentsarg)
|
|
|
|
|
2013-03-06 09:59:45 -06:00
|
|
|
if ret < 0 {
|
2013-03-05 13:53:04 -06:00
|
|
|
return nil, LastError()
|
|
|
|
}
|
|
|
|
|
|
|
|
return oid, nil
|
|
|
|
}
|
|
|
|
|
2013-03-05 18:43:48 -06:00
|
|
|
func (v *Odb) Free() {
|
|
|
|
runtime.SetFinalizer(v, nil)
|
|
|
|
C.git_odb_free(v.ptr)
|
2013-03-05 13:53:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Repository) Odb() (odb *Odb, err error) {
|
|
|
|
odb = new(Odb)
|
2013-09-18 02:23:47 -05:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
if ret := C.git_repository_odb(&odb.ptr, v.ptr); ret < 0 {
|
|
|
|
return nil, LastError()
|
|
|
|
}
|
|
|
|
|
2013-03-05 18:43:48 -06:00
|
|
|
runtime.SetFinalizer(odb, (*Odb).Free)
|
2013-03-05 13:53:04 -06:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2013-03-06 10:16:32 -06:00
|
|
|
func (repo *Repository) Path() string {
|
|
|
|
return C.GoString(C.git_repository_path(repo.ptr))
|
|
|
|
}
|
|
|
|
|
2013-11-14 05:08:34 -06:00
|
|
|
func (repo *Repository) IsBare() bool {
|
2013-04-25 17:10:28 -05:00
|
|
|
return C.git_repository_is_bare(repo.ptr) != 0
|
|
|
|
}
|
|
|
|
|
2013-03-06 13:10:48 -06:00
|
|
|
func (repo *Repository) Workdir() string {
|
|
|
|
return C.GoString(C.git_repository_workdir(repo.ptr))
|
|
|
|
}
|
|
|
|
|
2013-03-19 16:54:08 -05:00
|
|
|
func (repo *Repository) SetWorkdir(workdir string, updateGitlink bool) error {
|
|
|
|
cstr := C.CString(workdir)
|
|
|
|
defer C.free(unsafe.Pointer(cstr))
|
|
|
|
|
2013-09-18 02:23:47 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-03-19 16:54:08 -05:00
|
|
|
if C.git_repository_set_workdir(repo.ptr, cstr, cbool(updateGitlink)) < 0 {
|
|
|
|
return LastError()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
func (v *Repository) TreeBuilder() (*TreeBuilder, error) {
|
|
|
|
bld := new(TreeBuilder)
|
2013-09-18 02:23:47 -05:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-03-05 13:53:04 -06:00
|
|
|
if ret := C.git_treebuilder_create(&bld.ptr, nil); ret < 0 {
|
|
|
|
return nil, LastError()
|
|
|
|
}
|
2013-11-14 05:08:34 -06:00
|
|
|
runtime.SetFinalizer(bld, (*TreeBuilder).Free)
|
2013-03-05 13:53:04 -06:00
|
|
|
|
|
|
|
bld.repo = v
|
|
|
|
return bld, nil
|
|
|
|
}
|
|
|
|
|
2013-04-16 16:18:35 -05:00
|
|
|
func (v *Repository) RevparseSingle(spec string) (Object, error) {
|
|
|
|
cspec := C.CString(spec)
|
|
|
|
defer C.free(unsafe.Pointer(cspec))
|
|
|
|
|
|
|
|
var ptr *C.git_object
|
2013-09-18 02:23:47 -05:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-04-16 16:18:35 -05:00
|
|
|
ecode := C.git_revparse_single(&ptr, v.ptr, cspec)
|
|
|
|
if ecode < 0 {
|
|
|
|
return nil, LastError()
|
|
|
|
}
|
|
|
|
|
|
|
|
return allocObject(ptr), nil
|
|
|
|
}
|