git2go/repository.go

429 lines
8.9 KiB
Go
Raw Normal View History

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))
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, MakeGitError(ret)
2013-03-05 13:53:04 -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))
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, MakeGitError(ret)
2013-03-05 13:53:04 -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) {
2014-02-24 02:01:47 -06:00
repo = new(Repository)
2014-02-24 02:01:47 -06:00
ret := C.git_repository_wrap_odb(&repo.ptr, odb.ptr)
if ret < 0 {
return nil, LastError()
}
2014-02-24 02:01:47 -06:00
runtime.SetFinalizer(repo, (*Repository).Free)
2014-04-03 15:39:21 -05:00
return repo, nil
2014-02-24 02:01:47 -06:00
}
func (v *Repository) SetRefdb(refdb *Refdb) {
C.git_repository_set_refdb(v.ptr, refdb.ptr)
}
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)
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, MakeGitError(ret)
2013-03-05 13:53:04 -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
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, MakeGitError(ret)
2013-03-06 06:10:53 -06:00
}
return newIndexFromC(ptr), nil
}
func (v *Repository) lookupType(id *Oid, t ObjectType) (Object, error) {
2013-04-16 16:04:35 -05:00
var ptr *C.git_object
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_object_lookup(&ptr, v.ptr, id.toC(), C.git_otype(t))
2013-03-05 13:53:04 -06:00
if ret < 0 {
return nil, MakeGitError(ret)
2013-03-05 13:53:04 -06:00
}
2013-04-16 16:04:35 -05:00
return allocObject(ptr), nil
2013-03-05 13:53:04 -06:00
}
func (v *Repository) Lookup(id *Oid) (Object, error) {
return v.lookupType(id, ObjectAny)
2013-04-16 16:18:35 -05:00
}
func (v *Repository) LookupTree(id *Oid) (*Tree, error) {
obj, err := v.lookupType(id, 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
}
func (v *Repository) LookupCommit(id *Oid) (*Commit, error) {
obj, err := v.lookupType(id, ObjectCommit)
2013-04-16 16:04:35 -05:00
if err != nil {
return nil, err
}
return obj.(*Commit), nil
}
func (v *Repository) LookupBlob(id *Oid) (*Blob, error) {
obj, err := v.lookupType(id, ObjectBlob)
2013-04-16 16:04:35 -05:00
if err != nil {
return nil, err
}
2013-04-16 16:04:35 -05:00
return obj.(*Blob), nil
}
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
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, MakeGitError(ecode)
2013-03-06 11:29:43 -06:00
}
return newReferenceFromC(ptr), nil
}
func (v *Repository) CreateReference(name string, id *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))
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))
}
2013-03-06 11:29:43 -06:00
var ptr *C.git_reference
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_reference_create(&ptr, v.ptr, cname, id.toC(), cbool(force), csig, cmsg)
2013-03-06 11:29:43 -06:00
if ecode < 0 {
return nil, MakeGitError(ecode)
2013-03-06 11:29:43 -06:00
}
return newReferenceFromC(ptr), nil
}
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))
2013-03-06 11:29:43 -06:00
ctarget := C.CString(target)
defer C.free(unsafe.Pointer(ctarget))
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))
}
2013-03-06 11:29:43 -06:00
var ptr *C.git_reference
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_reference_symbolic_create(&ptr, v.ptr, cname, ctarget, cbool(force), csig, cmsg)
2013-03-06 11:29:43 -06:00
if ecode < 0 {
return nil, MakeGitError(ecode)
2013-03-06 11:29:43 -06:00
}
return newReferenceFromC(ptr), nil
}
2013-03-05 14:47:55 -06:00
func (v *Repository) Walk() (*RevWalk, error) {
var walkPtr *C.git_revwalk
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_revwalk_new(&walkPtr, v.ptr)
2013-03-05 14:47:55 -06:00
if ecode < 0 {
return nil, MakeGitError(ecode)
2013-03-05 14:47:55 -06:00
}
return revWalkFromC(v, walkPtr), nil
2013-03-05 14:47:55 -06:00
}
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.cast_ptr
2013-03-05 13:53:04 -06:00
}
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)
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,
nil, cmsg, tree.cast_ptr, C.size_t(nparents), parentsarg)
2013-03-05 13:53:04 -06:00
2013-03-06 09:59:45 -06:00
if ret < 0 {
return nil, MakeGitError(ret)
2013-03-05 13:53:04 -06:00
}
return oid, nil
}
func (v *Odb) Free() {
runtime.SetFinalizer(v, nil)
C.git_odb_free(v.ptr)
2013-03-05 13:53:04 -06:00
}
2014-02-24 02:01:47 -06:00
func (v *Refdb) Free() {
runtime.SetFinalizer(v, nil)
C.git_refdb_free(v.ptr)
}
2013-03-05 13:53:04 -06:00
func (v *Repository) Odb() (odb *Odb, err error) {
odb = new(Odb)
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, MakeGitError(ret)
2013-03-05 13:53:04 -06:00
}
runtime.SetFinalizer(odb, (*Odb).Free)
2014-04-03 15:39:21 -05:00
return odb, nil
2013-03-05 13:53:04 -06:00
}
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))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if ret := C.git_repository_set_workdir(repo.ptr, cstr, cbool(updateGitlink)); ret < 0 {
return MakeGitError(ret)
2013-03-19 16:54:08 -05:00
}
2013-03-19 16:54:08 -05:00
return nil
}
2013-03-05 13:53:04 -06:00
func (v *Repository) TreeBuilder() (*TreeBuilder, error) {
bld := new(TreeBuilder)
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, MakeGitError(ret)
2013-03-05 13:53:04 -06:00
}
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
}
func (v *Repository) TreeBuilderFromTree(tree *Tree) (*TreeBuilder, error) {
bld := new(TreeBuilder)
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if ret := C.git_treebuilder_create(&bld.ptr, tree.cast_ptr); ret < 0 {
return nil, MakeGitError(ret)
2013-03-05 13:53:04 -06:00
}
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
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, MakeGitError(ecode)
2013-04-16 16:18:35 -05:00
}
return allocObject(ptr), nil
}
2014-02-26 07:51:04 -06:00
// EnsureLog ensures that there is a reflog for the given reference
// name and creates an empty one if necessary.
func (v *Repository) EnsureLog(name string) error {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if ret := C.git_reference_ensure_log(v.ptr, cname); ret < 0 {
return MakeGitError(ret)
2014-02-26 07:51:04 -06:00
}
return nil
}
// HasLog returns whether there is a reflog for the given reference
// name
func (v *Repository) HasLog(name string) (bool, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_reference_has_log(v.ptr, cname)
if ret < 0 {
return false, MakeGitError(ret)
2014-02-26 07:51:04 -06:00
}
return ret == 1, nil
}
// DwimReference looks up a reference by DWIMing its short name
func (v *Repository) DwimReference(name string) (*Reference, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
var ptr *C.git_reference
if ret := C.git_reference_dwim(&ptr, v.ptr, cname); ret < 0 {
return nil, MakeGitError(ret)
2014-02-26 07:51:04 -06:00
}
return newReferenceFromC(ptr), nil
}