@@ -99,7 +99,7 @@ func (r *commitsTable) WithProjectAndFilters(
9999 return nil , err
100100 }
101101
102- return & commitsByHashIter {hashes : hashes }, nil
102+ return & commitIter {hashes : hashes }, nil
103103 },
104104 )
105105
@@ -114,10 +114,11 @@ func (r *commitsTable) WithProjectAndFilters(
114114type commitIter struct {
115115 repoID string
116116 iter object.CommitIter
117+ hashes []string
117118}
118119
119120func (i * commitIter ) NewIterator (repo * Repository ) (RowRepoIter , error ) {
120- iter , err := repo . Repo . CommitObjects ( )
121+ iter , err := NewCommitsByHashIter ( repo , i . hashes )
121122 if err != nil {
122123 return nil , err
123124 }
@@ -142,41 +143,6 @@ func (i *commitIter) Close() error {
142143 return nil
143144}
144145
145- type commitsByHashIter struct {
146- repo * Repository
147- pos int
148- hashes []string
149- }
150-
151- func (i * commitsByHashIter ) NewIterator (repo * Repository ) (RowRepoIter , error ) {
152- return & commitsByHashIter {repo , 0 , i .hashes }, nil
153- }
154-
155- func (i * commitsByHashIter ) Next () (sql.Row , error ) {
156- for {
157- if i .pos >= len (i .hashes ) {
158- return nil , io .EOF
159- }
160-
161- hash := plumbing .NewHash (i .hashes [i .pos ])
162- i .pos ++
163- commit , err := i .repo .Repo .CommitObject (hash )
164- if err == plumbing .ErrObjectNotFound {
165- continue
166- }
167-
168- if err != nil {
169- return nil , err
170- }
171-
172- return commitToRow (i .repo .ID , commit ), nil
173- }
174- }
175-
176- func (i * commitsByHashIter ) Close () error {
177- return nil
178- }
179-
180146func commitToRow (repoID string , c * object.Commit ) sql.Row {
181147 return sql .NewRow (
182148 repoID ,
@@ -201,3 +167,85 @@ func getParentHashes(c *object.Commit) []interface{} {
201167
202168 return parentHashes
203169}
170+
171+ type commitsByHashIter struct {
172+ repo * Repository
173+ hashes []string
174+ pos int
175+ commitIter object.CommitIter
176+ }
177+
178+ // NewCommitsByHashIter creates a CommitIter that can use a list of hashes
179+ // to iterate. If the list is empty it scans all commits.
180+ func NewCommitsByHashIter (
181+ repo * Repository ,
182+ hashes []string ,
183+ ) (object.CommitIter , error ) {
184+ var commitIter object.CommitIter
185+ var err error
186+ if len (hashes ) == 0 {
187+ commitIter , err = repo .Repo .CommitObjects ()
188+ if err != nil {
189+ return nil , err
190+ }
191+ }
192+
193+ return & commitsByHashIter {
194+ repo : repo ,
195+ hashes : hashes ,
196+ commitIter : commitIter ,
197+ }, nil
198+ }
199+
200+ func (i * commitsByHashIter ) Next () (* object.Commit , error ) {
201+ if i .commitIter != nil {
202+ return i .nextScan ()
203+ }
204+
205+ return i .nextList ()
206+ }
207+
208+ func (i * commitsByHashIter ) ForEach (f func (* object.Commit ) error ) error {
209+ for {
210+ c , err := i .Next ()
211+ if err != nil {
212+ return err
213+ }
214+
215+ err = f (c )
216+ if err != nil {
217+ return err
218+ }
219+ }
220+ }
221+
222+ func (i * commitsByHashIter ) Close () {
223+ if i .commitIter != nil {
224+ i .commitIter .Close ()
225+ }
226+ }
227+
228+ func (i * commitsByHashIter ) nextScan () (* object.Commit , error ) {
229+ return i .commitIter .Next ()
230+ }
231+
232+ func (i * commitsByHashIter ) nextList () (* object.Commit , error ) {
233+ for {
234+ if i .pos >= len (i .hashes ) {
235+ return nil , io .EOF
236+ }
237+
238+ hash := plumbing .NewHash (i .hashes [i .pos ])
239+ i .pos ++
240+ commit , err := i .repo .Repo .CommitObject (hash )
241+ if err == plumbing .ErrObjectNotFound {
242+ continue
243+ }
244+
245+ if err != nil {
246+ return nil , err
247+ }
248+
249+ return commit , nil
250+ }
251+ }
0 commit comments