summaryrefslogtreecommitdiff
path: root/reference.go
diff options
context:
space:
mode:
Diffstat (limited to 'reference.go')
-rw-r--r--reference.go73
1 files changed, 73 insertions, 0 deletions
diff --git a/reference.go b/reference.go
index 820d166..93ab7de 100644
--- a/reference.go
+++ b/reference.go
@@ -111,3 +111,76 @@ func (v *Reference) Free() {
runtime.SetFinalizer(v, nil)
C.git_reference_free(v.ptr)
}
+
+type ReferenceIterator struct {
+ ptr *C.git_reference_iterator
+ repo *Repository
+}
+
+// NewReferenceIterator creates a new iterator over reference names
+func (repo *Repository) NewReferenceIterator() (*ReferenceIterator, error) {
+ var ptr *C.git_reference_iterator
+ ret := C.git_reference_iterator_new(&ptr, repo.ptr)
+ if ret < 0 {
+ return nil, LastError()
+ }
+
+ iter := &ReferenceIterator{repo: repo, ptr: ptr}
+ runtime.SetFinalizer(iter, (*ReferenceIterator).Free)
+ return iter, nil
+}
+
+// NewReferenceIteratorGlob creates an iterator over reference names
+// that match the speicified glob. The glob is of the usual fnmatch
+// type.
+func (repo *Repository) NewReferenceIteratorGlob(glob string) (*ReferenceIterator, error) {
+ cstr := C.CString(glob)
+ defer C.free(unsafe.Pointer(cstr))
+ var ptr *C.git_reference_iterator
+ ret := C.git_reference_iterator_glob_new(&ptr, repo.ptr, cstr)
+ if ret < 0 {
+ return nil, LastError()
+ }
+
+ iter := &ReferenceIterator{repo: repo, ptr: ptr}
+ runtime.SetFinalizer(iter, (*ReferenceIterator).Free)
+ return iter, nil
+}
+
+// Next retrieves the next reference name. If the iteration is over,
+// the returned error is git.ErrIterOver
+func (v *ReferenceIterator) Next() (string, error) {
+ var ptr *C.char
+ ret := C.git_reference_next(&ptr, v.ptr)
+ if ret == ITEROVER {
+ return "", ErrIterOver
+ }
+ if ret < 0 {
+ return "", LastError()
+ }
+
+ return C.GoString(ptr), nil
+}
+
+// Create a channel from the iterator. You can use range on the
+// returned channel to iterate over all the references. The channel
+// will be closed in case any error is found.
+func (v *ReferenceIterator) Iter() <-chan string {
+ ch := make(chan string)
+ go func() {
+ defer close(ch)
+ name, err := v.Next()
+ for err == nil {
+ ch <- name
+ name, err = v.Next()
+ }
+ }()
+
+ return ch
+}
+
+// Free the reference iterator
+func (v *ReferenceIterator) Free() {
+ runtime.SetFinalizer(v, nil)
+ C.git_reference_iterator_free(v.ptr)
+}