diff options
Diffstat (limited to 'vendor/github.com/libgit2/git2go/branch.go')
-rw-r--r-- | vendor/github.com/libgit2/git2go/branch.go | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/vendor/github.com/libgit2/git2go/branch.go b/vendor/github.com/libgit2/git2go/branch.go new file mode 100644 index 000000000..d6e7a5323 --- /dev/null +++ b/vendor/github.com/libgit2/git2go/branch.go @@ -0,0 +1,262 @@ +package git + +/* +#include <git2.h> +*/ +import "C" + +import ( + "runtime" + "unsafe" +) + +type BranchType uint + +const ( + BranchAll BranchType = C.GIT_BRANCH_ALL + BranchLocal BranchType = C.GIT_BRANCH_LOCAL + BranchRemote BranchType = C.GIT_BRANCH_REMOTE +) + +type Branch struct { + *Reference +} + +func (r *Reference) Branch() *Branch { + return &Branch{Reference: r} +} + +type BranchIterator struct { + ptr *C.git_branch_iterator + repo *Repository +} + +type BranchIteratorFunc func(*Branch, BranchType) error + +func newBranchIteratorFromC(repo *Repository, ptr *C.git_branch_iterator) *BranchIterator { + i := &BranchIterator{repo: repo, ptr: ptr} + runtime.SetFinalizer(i, (*BranchIterator).Free) + return i +} + +func (i *BranchIterator) Next() (*Branch, BranchType, error) { + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + var refPtr *C.git_reference + var refType C.git_branch_t + + ecode := C.git_branch_next(&refPtr, &refType, i.ptr) + + if ecode < 0 { + return nil, BranchLocal, MakeGitError(ecode) + } + + branch := newReferenceFromC(refPtr, i.repo).Branch() + + return branch, BranchType(refType), nil +} + +func (i *BranchIterator) Free() { + runtime.SetFinalizer(i, nil) + C.git_branch_iterator_free(i.ptr) +} + +func (i *BranchIterator) ForEach(f BranchIteratorFunc) error { + b, t, err := i.Next() + + for err == nil { + err = f(b, t) + if err == nil { + b, t, err = i.Next() + } + } + + if err != nil && IsErrorCode(err, ErrIterOver) { + return nil + } + + return err +} + +func (repo *Repository) NewBranchIterator(flags BranchType) (*BranchIterator, error) { + refType := C.git_branch_t(flags) + var ptr *C.git_branch_iterator + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ecode := C.git_branch_iterator_new(&ptr, repo.ptr, refType) + runtime.KeepAlive(repo) + if ecode < 0 { + return nil, MakeGitError(ecode) + } + + return newBranchIteratorFromC(repo, ptr), nil +} + +func (repo *Repository) CreateBranch(branchName string, target *Commit, force bool) (*Branch, error) { + + var ptr *C.git_reference + cBranchName := C.CString(branchName) + defer C.free(unsafe.Pointer(cBranchName)) + cForce := cbool(force) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_branch_create(&ptr, repo.ptr, cBranchName, target.cast_ptr, cForce) + runtime.KeepAlive(repo) + runtime.KeepAlive(target) + if ret < 0 { + return nil, MakeGitError(ret) + } + return newReferenceFromC(ptr, repo).Branch(), nil +} + +func (b *Branch) Delete() error { + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_branch_delete(b.Reference.ptr) + runtime.KeepAlive(b.Reference) + if ret < 0 { + return MakeGitError(ret) + } + return nil +} + +func (b *Branch) Move(newBranchName string, force bool) (*Branch, error) { + var ptr *C.git_reference + cNewBranchName := C.CString(newBranchName) + defer C.free(unsafe.Pointer(cNewBranchName)) + cForce := cbool(force) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_branch_move(&ptr, b.Reference.ptr, cNewBranchName, cForce) + runtime.KeepAlive(b.Reference) + if ret < 0 { + return nil, MakeGitError(ret) + } + return newReferenceFromC(ptr, b.repo).Branch(), nil +} + +func (b *Branch) IsHead() (bool, error) { + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_branch_is_head(b.Reference.ptr) + runtime.KeepAlive(b.Reference) + switch ret { + case 1: + return true, nil + case 0: + return false, nil + } + return false, MakeGitError(ret) + +} + +func (repo *Repository) LookupBranch(branchName string, bt BranchType) (*Branch, error) { + var ptr *C.git_reference + + cName := C.CString(branchName) + defer C.free(unsafe.Pointer(cName)) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_branch_lookup(&ptr, repo.ptr, cName, C.git_branch_t(bt)) + runtime.KeepAlive(repo) + if ret < 0 { + return nil, MakeGitError(ret) + } + return newReferenceFromC(ptr, repo).Branch(), nil +} + +func (b *Branch) Name() (string, error) { + var cName *C.char + defer C.free(unsafe.Pointer(cName)) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_branch_name(&cName, b.Reference.ptr) + runtime.KeepAlive(b.Reference) + if ret < 0 { + return "", MakeGitError(ret) + } + + return C.GoString(cName), nil +} + +func (repo *Repository) RemoteName(canonicalBranchName string) (string, error) { + cName := C.CString(canonicalBranchName) + defer C.free(unsafe.Pointer(cName)) + + nameBuf := C.git_buf{} + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_branch_remote_name(&nameBuf, repo.ptr, cName) + runtime.KeepAlive(repo) + if ret < 0 { + return "", MakeGitError(ret) + } + defer C.git_buf_free(&nameBuf) + + return C.GoString(nameBuf.ptr), nil +} + +func (b *Branch) SetUpstream(upstreamName string) error { + cName := C.CString(upstreamName) + defer C.free(unsafe.Pointer(cName)) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_branch_set_upstream(b.Reference.ptr, cName) + runtime.KeepAlive(b.Reference) + if ret < 0 { + return MakeGitError(ret) + } + return nil +} + +func (b *Branch) Upstream() (*Reference, error) { + + var ptr *C.git_reference + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_branch_upstream(&ptr, b.Reference.ptr) + runtime.KeepAlive(b.Reference) + if ret < 0 { + return nil, MakeGitError(ret) + } + return newReferenceFromC(ptr, b.repo), nil +} + +func (repo *Repository) UpstreamName(canonicalBranchName string) (string, error) { + cName := C.CString(canonicalBranchName) + defer C.free(unsafe.Pointer(cName)) + + nameBuf := C.git_buf{} + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_branch_upstream_name(&nameBuf, repo.ptr, cName) + runtime.KeepAlive(repo) + if ret < 0 { + return "", MakeGitError(ret) + } + defer C.git_buf_free(&nameBuf) + + return C.GoString(nameBuf.ptr), nil +} |