2013-03-06 11:29:43 -06:00
|
|
|
package git
|
|
|
|
|
|
|
|
/*
|
|
|
|
#include <git2.h>
|
|
|
|
*/
|
|
|
|
import "C"
|
|
|
|
import (
|
|
|
|
"runtime"
|
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
2013-09-12 03:46:20 -05:00
|
|
|
type ReferenceType int
|
2014-01-29 17:01:26 -06:00
|
|
|
|
2013-09-12 03:40:57 -05:00
|
|
|
const (
|
2013-09-12 03:46:20 -05:00
|
|
|
ReferenceSymbolic ReferenceType = C.GIT_REF_SYMBOLIC
|
2014-10-27 09:12:18 -05:00
|
|
|
ReferenceOid ReferenceType = C.GIT_REF_OID
|
2013-03-06 11:29:43 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
type Reference struct {
|
2014-05-26 02:28:07 -05:00
|
|
|
ptr *C.git_reference
|
|
|
|
repo *Repository
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
2015-06-27 18:12:32 -05:00
|
|
|
type ReferenceCollection struct {
|
|
|
|
repo *Repository
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ReferenceCollection) Lookup(name string) (*Reference, error) {
|
|
|
|
cname := C.CString(name)
|
|
|
|
defer C.free(unsafe.Pointer(cname))
|
|
|
|
var ptr *C.git_reference
|
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
|
|
|
ecode := C.git_reference_lookup(&ptr, c.repo.ptr, cname)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(c)
|
2015-06-27 18:12:32 -05:00
|
|
|
if ecode < 0 {
|
|
|
|
return nil, MakeGitError(ecode)
|
|
|
|
}
|
|
|
|
|
|
|
|
return newReferenceFromC(ptr, c.repo), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ReferenceCollection) Create(name string, id *Oid, force bool, msg string) (*Reference, error) {
|
|
|
|
cname := C.CString(name)
|
|
|
|
defer C.free(unsafe.Pointer(cname))
|
|
|
|
|
|
|
|
var cmsg *C.char
|
|
|
|
if msg == "" {
|
|
|
|
cmsg = nil
|
|
|
|
} else {
|
|
|
|
cmsg = C.CString(msg)
|
|
|
|
defer C.free(unsafe.Pointer(cmsg))
|
|
|
|
}
|
|
|
|
|
|
|
|
var ptr *C.git_reference
|
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
|
|
|
ecode := C.git_reference_create(&ptr, c.repo.ptr, cname, id.toC(), cbool(force), cmsg)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(c)
|
|
|
|
runtime.KeepAlive(id)
|
2015-06-27 18:12:32 -05:00
|
|
|
if ecode < 0 {
|
|
|
|
return nil, MakeGitError(ecode)
|
|
|
|
}
|
|
|
|
|
|
|
|
return newReferenceFromC(ptr, c.repo), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *ReferenceCollection) CreateSymbolic(name, target string, force bool, msg string) (*Reference, error) {
|
|
|
|
cname := C.CString(name)
|
|
|
|
defer C.free(unsafe.Pointer(cname))
|
|
|
|
|
|
|
|
ctarget := C.CString(target)
|
|
|
|
defer C.free(unsafe.Pointer(ctarget))
|
|
|
|
|
|
|
|
var cmsg *C.char
|
|
|
|
if msg == "" {
|
|
|
|
cmsg = nil
|
|
|
|
} else {
|
|
|
|
cmsg = C.CString(msg)
|
|
|
|
defer C.free(unsafe.Pointer(cmsg))
|
|
|
|
}
|
|
|
|
|
|
|
|
var ptr *C.git_reference
|
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
|
|
|
ecode := C.git_reference_symbolic_create(&ptr, c.repo.ptr, cname, ctarget, cbool(force), cmsg)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(c)
|
2015-06-27 18:12:32 -05:00
|
|
|
if ecode < 0 {
|
|
|
|
return nil, MakeGitError(ecode)
|
|
|
|
}
|
|
|
|
|
|
|
|
return newReferenceFromC(ptr, c.repo), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// EnsureLog ensures that there is a reflog for the given reference
|
|
|
|
// name and creates an empty one if necessary.
|
|
|
|
func (c *ReferenceCollection) EnsureLog(name string) error {
|
|
|
|
cname := C.CString(name)
|
|
|
|
defer C.free(unsafe.Pointer(cname))
|
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
|
|
|
ret := C.git_reference_ensure_log(c.repo.ptr, cname)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(c)
|
2015-06-27 18:12:32 -05:00
|
|
|
if ret < 0 {
|
|
|
|
return MakeGitError(ret)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// HasLog returns whether there is a reflog for the given reference
|
|
|
|
// name
|
|
|
|
func (c *ReferenceCollection) 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(c.repo.ptr, cname)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(c)
|
2015-06-27 18:12:32 -05:00
|
|
|
if ret < 0 {
|
|
|
|
return false, MakeGitError(ret)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret == 1, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dwim looks up a reference by DWIMing its short name
|
|
|
|
func (c *ReferenceCollection) Dwim(name string) (*Reference, error) {
|
|
|
|
cname := C.CString(name)
|
|
|
|
defer C.free(unsafe.Pointer(cname))
|
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
|
|
|
var ptr *C.git_reference
|
|
|
|
ret := C.git_reference_dwim(&ptr, c.repo.ptr, cname)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(c)
|
2015-06-27 18:12:32 -05:00
|
|
|
if ret < 0 {
|
|
|
|
return nil, MakeGitError(ret)
|
|
|
|
}
|
|
|
|
|
|
|
|
return newReferenceFromC(ptr, c.repo), nil
|
|
|
|
}
|
|
|
|
|
2014-05-26 02:28:07 -05:00
|
|
|
func newReferenceFromC(ptr *C.git_reference, repo *Repository) *Reference {
|
|
|
|
ref := &Reference{ptr: ptr, repo: repo}
|
2013-03-06 11:29:43 -06:00
|
|
|
runtime.SetFinalizer(ref, (*Reference).Free)
|
|
|
|
return ref
|
|
|
|
}
|
|
|
|
|
2015-03-14 19:49:32 -05:00
|
|
|
func (v *Reference) SetSymbolicTarget(target string, msg string) (*Reference, error) {
|
2013-03-06 11:29:43 -06:00
|
|
|
var ptr *C.git_reference
|
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))
|
|
|
|
|
2013-09-18 02:23:47 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2014-02-26 08:01:23 -06:00
|
|
|
var cmsg *C.char
|
|
|
|
if msg == "" {
|
|
|
|
cmsg = nil
|
|
|
|
} else {
|
|
|
|
cmsg = C.CString(msg)
|
|
|
|
defer C.free(unsafe.Pointer(cmsg))
|
|
|
|
}
|
2014-01-29 17:01:26 -06:00
|
|
|
|
2015-03-14 19:49:32 -05:00
|
|
|
ret := C.git_reference_symbolic_set_target(&ptr, v.ptr, ctarget, cmsg)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
2013-03-06 11:29:43 -06:00
|
|
|
if ret < 0 {
|
2013-07-07 09:43:44 -05:00
|
|
|
return nil, MakeGitError(ret)
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
2014-05-26 02:28:07 -05:00
|
|
|
return newReferenceFromC(ptr, v.repo), nil
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
2015-03-14 19:49:32 -05:00
|
|
|
func (v *Reference) SetTarget(target *Oid, msg string) (*Reference, error) {
|
2013-03-06 11:29:43 -06:00
|
|
|
var ptr *C.git_reference
|
|
|
|
|
2013-09-18 02:23:47 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2014-02-26 08:01:23 -06:00
|
|
|
var cmsg *C.char
|
|
|
|
if msg == "" {
|
|
|
|
cmsg = nil
|
|
|
|
} else {
|
|
|
|
cmsg = C.CString(msg)
|
|
|
|
defer C.free(unsafe.Pointer(cmsg))
|
|
|
|
}
|
2014-01-29 17:01:26 -06:00
|
|
|
|
2015-03-14 19:49:32 -05:00
|
|
|
ret := C.git_reference_set_target(&ptr, v.ptr, target.toC(), cmsg)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
2013-03-06 11:29:43 -06:00
|
|
|
if ret < 0 {
|
2013-07-07 09:43:44 -05:00
|
|
|
return nil, MakeGitError(ret)
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
2014-05-26 02:28:07 -05:00
|
|
|
return newReferenceFromC(ptr, v.repo), nil
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Reference) Resolve() (*Reference, error) {
|
|
|
|
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
|
|
|
ret := C.git_reference_resolve(&ptr, v.ptr)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
2013-03-06 11:29:43 -06:00
|
|
|
if ret < 0 {
|
2013-07-07 09:43:44 -05:00
|
|
|
return nil, MakeGitError(ret)
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
2014-05-26 02:28:07 -05:00
|
|
|
return newReferenceFromC(ptr, v.repo), nil
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
2015-03-14 19:49:32 -05:00
|
|
|
func (v *Reference) Rename(name string, force bool, msg string) (*Reference, error) {
|
2013-03-06 11:29:43 -06:00
|
|
|
var ptr *C.git_reference
|
|
|
|
cname := C.CString(name)
|
|
|
|
defer C.free(unsafe.Pointer(cname))
|
|
|
|
|
2014-02-26 08:01:23 -06:00
|
|
|
var cmsg *C.char
|
|
|
|
if msg == "" {
|
|
|
|
cmsg = nil
|
|
|
|
} else {
|
|
|
|
cmsg = C.CString(msg)
|
|
|
|
defer C.free(unsafe.Pointer(cmsg))
|
|
|
|
}
|
2014-02-23 08:31:22 -06:00
|
|
|
|
2013-09-18 02:23:47 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2015-03-14 19:49:32 -05:00
|
|
|
ret := C.git_reference_rename(&ptr, v.ptr, cname, cbool(force), cmsg)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
2013-03-06 11:29:43 -06:00
|
|
|
if ret < 0 {
|
2013-07-07 09:43:44 -05:00
|
|
|
return nil, MakeGitError(ret)
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
2014-05-26 02:28:07 -05:00
|
|
|
return newReferenceFromC(ptr, v.repo), nil
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Reference) Target() *Oid {
|
2017-07-08 09:07:51 -05:00
|
|
|
ret := newOidFromC(C.git_reference_target(v.ptr))
|
|
|
|
runtime.KeepAlive(v)
|
|
|
|
return ret
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Reference) SymbolicTarget() string {
|
2017-07-08 09:07:51 -05:00
|
|
|
var ret string
|
2013-03-06 11:29:43 -06:00
|
|
|
cstr := C.git_reference_symbolic_target(v.ptr)
|
2017-07-08 09:07:51 -05:00
|
|
|
|
|
|
|
if cstr != nil {
|
|
|
|
return C.GoString(cstr)
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
|
|
|
return ret
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Reference) Delete() error {
|
2013-09-18 02:23:47 -05:00
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-03-06 11:29:43 -06:00
|
|
|
ret := C.git_reference_delete(v.ptr)
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
2013-03-06 11:29:43 -06:00
|
|
|
if ret < 0 {
|
2013-07-07 09:43:44 -05:00
|
|
|
return MakeGitError(ret)
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2015-08-04 07:47:10 -05:00
|
|
|
func (v *Reference) Peel(t ObjectType) (*Object, error) {
|
2014-05-23 04:37:00 -05:00
|
|
|
var cobj *C.git_object
|
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2019-01-05 04:45:30 -06:00
|
|
|
err := C.git_reference_peel(&cobj, v.ptr, C.git_object_t(t))
|
2017-07-08 09:07:51 -05:00
|
|
|
runtime.KeepAlive(v)
|
|
|
|
if err < 0 {
|
2014-05-23 04:37:00 -05:00
|
|
|
return nil, MakeGitError(err)
|
|
|
|
}
|
|
|
|
|
2014-05-26 02:28:07 -05:00
|
|
|
return allocObject(cobj, v.repo), nil
|
2014-05-23 04:37:00 -05:00
|
|
|
}
|
|
|
|
|
2014-05-25 02:06:18 -05:00
|
|
|
// Owner returns a weak reference to the repository which owns this
|
|
|
|
// reference.
|
|
|
|
func (v *Reference) Owner() *Repository {
|
|
|
|
return &Repository{
|
|
|
|
ptr: C.git_reference_owner(v.ptr),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-15 11:39:26 -06:00
|
|
|
// Cmp compares v to ref2. It returns 0 on equality, otherwise a
|
2014-02-26 07:51:04 -06:00
|
|
|
// stable sorting.
|
|
|
|
func (v *Reference) Cmp(ref2 *Reference) int {
|
2017-07-08 09:07:51 -05:00
|
|
|
ret := int(C.git_reference_cmp(v.ptr, ref2.ptr))
|
|
|
|
runtime.KeepAlive(v)
|
|
|
|
runtime.KeepAlive(ref2)
|
|
|
|
return ret
|
2014-02-26 07:51:04 -06:00
|
|
|
}
|
|
|
|
|
2018-02-15 11:39:26 -06:00
|
|
|
// Shorthand returns a "human-readable" short reference name.
|
2014-02-26 07:51:04 -06:00
|
|
|
func (v *Reference) Shorthand() string {
|
2017-07-08 09:07:51 -05:00
|
|
|
ret := C.GoString(C.git_reference_shorthand(v.ptr))
|
|
|
|
runtime.KeepAlive(v)
|
|
|
|
return ret
|
2014-02-26 07:51:04 -06:00
|
|
|
}
|
|
|
|
|
2018-02-15 11:39:26 -06:00
|
|
|
// Name returns the full name of v.
|
2013-03-06 11:29:43 -06:00
|
|
|
func (v *Reference) Name() string {
|
2017-07-08 09:07:51 -05:00
|
|
|
ret := C.GoString(C.git_reference_name(v.ptr))
|
|
|
|
runtime.KeepAlive(v)
|
|
|
|
return ret
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
2013-09-12 03:46:20 -05:00
|
|
|
func (v *Reference) Type() ReferenceType {
|
2017-07-08 09:07:51 -05:00
|
|
|
ret := ReferenceType(C.git_reference_type(v.ptr))
|
|
|
|
runtime.KeepAlive(v)
|
|
|
|
return ret
|
2013-03-06 11:29:43 -06:00
|
|
|
}
|
|
|
|
|
2014-02-20 00:24:11 -06:00
|
|
|
func (v *Reference) IsBranch() bool {
|
2017-07-08 09:07:51 -05:00
|
|
|
ret := C.git_reference_is_branch(v.ptr) == 1
|
|
|
|
runtime.KeepAlive(v)
|
|
|
|
return ret
|
2014-02-20 00:24:11 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Reference) IsRemote() bool {
|
2017-07-08 09:07:51 -05:00
|
|
|
ret := C.git_reference_is_remote(v.ptr) == 1
|
|
|
|
runtime.KeepAlive(v)
|
|
|
|
return ret
|
2014-02-20 00:24:11 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Reference) IsTag() bool {
|
2017-07-08 09:07:51 -05:00
|
|
|
ret := C.git_reference_is_tag(v.ptr) == 1
|
|
|
|
runtime.KeepAlive(v)
|
|
|
|
return ret
|
2014-02-20 00:24:11 -06:00
|
|
|
}
|
|
|
|
|
2015-07-24 04:14:24 -05:00
|
|
|
// IsNote checks if the reference is a note.
|
|
|
|
func (v *Reference) IsNote() bool {
|
2017-07-08 09:07:51 -05:00
|
|
|
ret := C.git_reference_is_note(v.ptr) == 1
|
|
|
|
runtime.KeepAlive(v)
|
|
|
|
return ret
|
2015-07-24 04:14:24 -05:00
|
|
|
}
|
|
|
|
|
2013-03-06 11:29:43 -06:00
|
|
|
func (v *Reference) Free() {
|
|
|
|
runtime.SetFinalizer(v, nil)
|
|
|
|
C.git_reference_free(v.ptr)
|
|
|
|
}
|
2013-05-21 08:14:26 -05:00
|
|
|
|
2014-03-20 03:27:03 -05:00
|
|
|
type ReferenceIterator struct {
|
|
|
|
ptr *C.git_reference_iterator
|
|
|
|
repo *Repository
|
2014-03-19 02:19:02 -05:00
|
|
|
}
|
|
|
|
|
2014-03-20 03:27:03 -05:00
|
|
|
type ReferenceNameIterator struct {
|
|
|
|
*ReferenceIterator
|
2014-03-19 02:36:00 -05:00
|
|
|
}
|
|
|
|
|
2014-03-20 03:27:03 -05:00
|
|
|
// NewReferenceIterator creates a new iterator over reference names
|
|
|
|
func (repo *Repository) NewReferenceIterator() (*ReferenceIterator, error) {
|
|
|
|
var ptr *C.git_reference_iterator
|
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
|
|
|
ret := C.git_reference_iterator_new(&ptr, repo.ptr)
|
|
|
|
if ret < 0 {
|
|
|
|
return nil, MakeGitError(ret)
|
|
|
|
}
|
|
|
|
|
2017-07-08 09:07:51 -05:00
|
|
|
return newReferenceIteratorFromC(ptr, repo), nil
|
2013-05-21 08:14:26 -05:00
|
|
|
}
|
|
|
|
|
2014-04-04 02:27:07 -05:00
|
|
|
// NewReferenceIterator creates a new branch iterator over reference names
|
|
|
|
func (repo *Repository) NewReferenceNameIterator() (*ReferenceNameIterator, error) {
|
2013-05-21 08:14:26 -05:00
|
|
|
var ptr *C.git_reference_iterator
|
2013-09-18 02:23:47 -05:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-05-21 08:14:26 -05:00
|
|
|
ret := C.git_reference_iterator_new(&ptr, repo.ptr)
|
|
|
|
if ret < 0 {
|
2013-07-07 09:43:44 -05:00
|
|
|
return nil, MakeGitError(ret)
|
2013-05-21 08:14:26 -05:00
|
|
|
}
|
|
|
|
|
2017-07-08 09:07:51 -05:00
|
|
|
iter := newReferenceIteratorFromC(ptr, repo)
|
2014-04-04 02:27:07 -05:00
|
|
|
return iter.Names(), nil
|
2013-05-21 08:14:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewReferenceIteratorGlob creates an iterator over reference names
|
|
|
|
// that match the speicified glob. The glob is of the usual fnmatch
|
|
|
|
// type.
|
2014-03-20 03:27:03 -05:00
|
|
|
func (repo *Repository) NewReferenceIteratorGlob(glob string) (*ReferenceIterator, error) {
|
2013-05-21 08:14:26 -05:00
|
|
|
cstr := C.CString(glob)
|
|
|
|
defer C.free(unsafe.Pointer(cstr))
|
|
|
|
var ptr *C.git_reference_iterator
|
2013-09-18 02:23:47 -05:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-05-21 08:14:26 -05:00
|
|
|
ret := C.git_reference_iterator_glob_new(&ptr, repo.ptr, cstr)
|
|
|
|
if ret < 0 {
|
2013-07-07 09:43:44 -05:00
|
|
|
return nil, MakeGitError(ret)
|
2013-05-21 08:14:26 -05:00
|
|
|
}
|
|
|
|
|
2017-07-08 09:07:51 -05:00
|
|
|
return newReferenceIteratorFromC(ptr, repo), nil
|
2013-05-21 08:14:26 -05:00
|
|
|
}
|
|
|
|
|
2014-03-20 03:27:03 -05:00
|
|
|
func (i *ReferenceIterator) Names() *ReferenceNameIterator {
|
|
|
|
return &ReferenceNameIterator{i}
|
|
|
|
}
|
|
|
|
|
2013-08-09 11:22:26 -05:00
|
|
|
// NextName retrieves the next reference name. If the iteration is over,
|
2013-05-21 08:14:26 -05:00
|
|
|
// the returned error is git.ErrIterOver
|
2014-03-20 03:27:03 -05:00
|
|
|
func (v *ReferenceNameIterator) Next() (string, error) {
|
2013-05-21 08:14:26 -05:00
|
|
|
var ptr *C.char
|
2013-09-18 02:23:47 -05:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-06-16 19:08:13 -05:00
|
|
|
ret := C.git_reference_next_name(&ptr, v.ptr)
|
2013-05-21 08:14:26 -05:00
|
|
|
if ret < 0 {
|
2013-07-07 09:43:44 -05:00
|
|
|
return "", MakeGitError(ret)
|
2013-05-21 08:14:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return C.GoString(ptr), nil
|
|
|
|
}
|
|
|
|
|
2013-08-09 11:22:26 -05:00
|
|
|
// Next retrieves the next reference. If the iterationis over, the
|
|
|
|
// returned error is git.ErrIterOver
|
2014-03-20 03:27:03 -05:00
|
|
|
func (v *ReferenceIterator) Next() (*Reference, error) {
|
2013-08-09 11:22:26 -05:00
|
|
|
var ptr *C.git_reference
|
2014-12-05 19:44:57 -06:00
|
|
|
|
|
|
|
runtime.LockOSThread()
|
|
|
|
defer runtime.UnlockOSThread()
|
|
|
|
|
2013-08-09 11:22:26 -05:00
|
|
|
ret := C.git_reference_next(&ptr, v.ptr)
|
|
|
|
if ret < 0 {
|
2014-02-26 09:14:31 -06:00
|
|
|
return nil, MakeGitError(ret)
|
2013-08-09 11:22:26 -05:00
|
|
|
}
|
|
|
|
|
2014-05-26 02:28:07 -05:00
|
|
|
return newReferenceFromC(ptr, v.repo), nil
|
2013-08-09 11:22:26 -05:00
|
|
|
}
|
|
|
|
|
2017-07-08 09:07:51 -05:00
|
|
|
func newReferenceIteratorFromC(ptr *C.git_reference_iterator, r *Repository) *ReferenceIterator {
|
2018-05-30 16:15:59 -05:00
|
|
|
iter := &ReferenceIterator{
|
2017-07-08 09:07:51 -05:00
|
|
|
ptr: ptr,
|
|
|
|
repo: r,
|
|
|
|
}
|
2018-05-30 16:15:59 -05:00
|
|
|
runtime.SetFinalizer(iter, (*ReferenceIterator).Free)
|
|
|
|
return iter
|
2017-07-08 09:07:51 -05:00
|
|
|
}
|
|
|
|
|
2014-03-19 02:19:02 -05:00
|
|
|
// Free the reference iterator
|
2014-03-20 03:27:03 -05:00
|
|
|
func (v *ReferenceIterator) Free() {
|
2014-03-19 02:19:02 -05:00
|
|
|
runtime.SetFinalizer(v, nil)
|
|
|
|
C.git_reference_iterator_free(v.ptr)
|
|
|
|
}
|
2015-07-24 04:14:53 -05:00
|
|
|
|
|
|
|
// ReferenceIsValidName ensures the reference name is well-formed.
|
|
|
|
//
|
|
|
|
// Valid reference names must follow one of two patterns:
|
|
|
|
//
|
|
|
|
// 1. Top-level names must contain only capital letters and underscores,
|
|
|
|
// and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
|
|
|
|
//
|
|
|
|
// 2. Names prefixed with "refs/" can be almost anything. You must avoid
|
|
|
|
// the characters '~', '^', ':', ' \ ', '?', '[', and '*', and the sequences
|
|
|
|
// ".." and " @ {" which have special meaning to revparse.
|
|
|
|
func ReferenceIsValidName(name string) bool {
|
|
|
|
cname := C.CString(name)
|
|
|
|
defer C.free(unsafe.Pointer(cname))
|
|
|
|
if C.git_reference_is_valid_name(cname) == 1 {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|