@@ -131,9 +131,27 @@ func (iter *ReferenceSliceIter) Next() (*plumbing.Reference, error) {
131131// an error happens or the end of the iter is reached. If ErrStop is sent
132132// the iteration is stop but no error is returned. The iterator is closed.
133133func (iter * ReferenceSliceIter ) ForEach (cb func (* plumbing.Reference ) error ) error {
134+ return forEachReferenceIter (iter , cb )
135+ }
136+
137+ type bareReferenceIterator interface {
138+ Next () (* plumbing.Reference , error )
139+ Close ()
140+ }
141+
142+ func forEachReferenceIter (iter bareReferenceIterator , cb func (* plumbing.Reference ) error ) error {
134143 defer iter .Close ()
135- for _ , r := range iter .series {
136- if err := cb (r ); err != nil {
144+ for {
145+ obj , err := iter .Next ()
146+ if err != nil {
147+ if err == io .EOF {
148+ return nil
149+ }
150+
151+ return err
152+ }
153+
154+ if err := cb (obj ); err != nil {
137155 if err == ErrStop {
138156 return nil
139157 }
@@ -150,6 +168,52 @@ func (iter *ReferenceSliceIter) Close() {
150168 iter .pos = len (iter .series )
151169}
152170
171+ // MultiReferenceIter implements ReferenceIter. It iterates over several
172+ // ReferenceIter,
173+ //
174+ // The MultiReferenceIter must be closed with a call to Close() when it is no
175+ // longer needed.
176+ type MultiReferenceIter struct {
177+ iters []ReferenceIter
178+ }
179+
180+ // NewMultiReferenceIter returns an reference iterator for the given slice of
181+ // EncodedObjectIters.
182+ func NewMultiReferenceIter (iters []ReferenceIter ) ReferenceIter {
183+ return & MultiReferenceIter {iters : iters }
184+ }
185+
186+ // Next returns the next reference from the iterator, if one iterator reach
187+ // io.EOF is removed and the next one is used.
188+ func (iter * MultiReferenceIter ) Next () (* plumbing.Reference , error ) {
189+ if len (iter .iters ) == 0 {
190+ return nil , io .EOF
191+ }
192+
193+ obj , err := iter .iters [0 ].Next ()
194+ if err == io .EOF {
195+ iter .iters [0 ].Close ()
196+ iter .iters = iter .iters [1 :]
197+ return iter .Next ()
198+ }
199+
200+ return obj , err
201+ }
202+
203+ // ForEach call the cb function for each reference contained on this iter until
204+ // an error happens or the end of the iter is reached. If ErrStop is sent
205+ // the iteration is stop but no error is returned. The iterator is closed.
206+ func (iter * MultiReferenceIter ) ForEach (cb func (* plumbing.Reference ) error ) error {
207+ return forEachReferenceIter (iter , cb )
208+ }
209+
210+ // Close releases any resources used by the iterator.
211+ func (iter * MultiReferenceIter ) Close () {
212+ for _ , i := range iter .iters {
213+ i .Close ()
214+ }
215+ }
216+
153217// ResolveReference resolves a SymbolicReference to a HashReference.
154218func ResolveReference (s ReferenceStorer , n plumbing.ReferenceName ) (* plumbing.Reference , error ) {
155219 r , err := s .Reference (n )
0 commit comments