Skip to content

Commit 6bde5d4

Browse files
KarthikNayakgitster
authored andcommitted
refs: expose ref_iterator via 'refs.h'
The `ref_iterator` is an internal structure to the 'refs/' sub-directory, which allows iteration over refs. All reference iteration is built on top of these iterators. External clients of the 'refs' subsystem use the various 'refs_for_each...()' functions to iterate over refs. However since these are wrapper functions, each combination of functionality requires a new wrapper function. This is not feasible as the functions pile up with the increase in requirements. Expose the internal reference iterator, so advanced users can mix and match options as needed. Signed-off-by: Karthik Nayak <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 16bd9f2 commit 6bde5d4

File tree

2 files changed

+149
-143
lines changed

2 files changed

+149
-143
lines changed

refs.h

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,4 +1190,151 @@ int repo_migrate_ref_storage_format(struct repository *repo,
11901190
unsigned int flags,
11911191
struct strbuf *err);
11921192

1193+
/*
1194+
* Reference iterators
1195+
*
1196+
* A reference iterator encapsulates the state of an in-progress
1197+
* iteration over references. Create an instance of `struct
1198+
* ref_iterator` via one of the functions in this module.
1199+
*
1200+
* A freshly-created ref_iterator doesn't yet point at a reference. To
1201+
* advance the iterator, call ref_iterator_advance(). If successful,
1202+
* this sets the iterator's refname, oid, and flags fields to describe
1203+
* the next reference and returns ITER_OK. The data pointed at by
1204+
* refname and oid belong to the iterator; if you want to retain them
1205+
* after calling ref_iterator_advance() again or calling
1206+
* ref_iterator_free(), you must make a copy. When the iteration has
1207+
* been exhausted, ref_iterator_advance() releases any resources
1208+
* associated with the iteration, frees the ref_iterator object, and
1209+
* returns ITER_DONE. If you want to abort the iteration early, call
1210+
* ref_iterator_free(), which also frees the ref_iterator object and
1211+
* any associated resources. If there was an internal error advancing
1212+
* to the next entry, ref_iterator_advance() aborts the iteration,
1213+
* frees the ref_iterator, and returns ITER_ERROR.
1214+
*
1215+
* The reference currently being looked at can be peeled by calling
1216+
* ref_iterator_peel(). This function is often faster than peel_ref(),
1217+
* so it should be preferred when iterating over references.
1218+
*
1219+
* Putting it all together, a typical iteration looks like this:
1220+
*
1221+
* int ok;
1222+
* struct ref_iterator *iter = ...;
1223+
*
1224+
* while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
1225+
* if (want_to_stop_iteration()) {
1226+
* ok = ITER_DONE;
1227+
* break;
1228+
* }
1229+
*
1230+
* // Access information about the current reference:
1231+
* if (!(iter->flags & REF_ISSYMREF))
1232+
* printf("%s is %s\n", iter->refname, oid_to_hex(iter->oid));
1233+
*
1234+
* // If you need to peel the reference:
1235+
* ref_iterator_peel(iter, &oid);
1236+
* }
1237+
*
1238+
* if (ok != ITER_DONE)
1239+
* handle_error();
1240+
* ref_iterator_free(iter);
1241+
*/
1242+
struct ref_iterator;
1243+
1244+
/*
1245+
* These flags are passed to refs_ref_iterator_begin() (and do_for_each_ref(),
1246+
* which feeds it).
1247+
*/
1248+
enum do_for_each_ref_flags {
1249+
/*
1250+
* Include broken references in a do_for_each_ref*() iteration, which
1251+
* would normally be omitted. This includes both refs that point to
1252+
* missing objects (a true repository corruption), ones with illegal
1253+
* names (which we prefer not to expose to callers), as well as
1254+
* dangling symbolic refs (i.e., those that point to a non-existent
1255+
* ref; this is not a corruption, but as they have no valid oid, we
1256+
* omit them from normal iteration results).
1257+
*/
1258+
DO_FOR_EACH_INCLUDE_BROKEN = (1 << 0),
1259+
1260+
/*
1261+
* Only include per-worktree refs in a do_for_each_ref*() iteration.
1262+
* Normally this will be used with a files ref_store, since that's
1263+
* where all reference backends will presumably store their
1264+
* per-worktree refs.
1265+
*/
1266+
DO_FOR_EACH_PER_WORKTREE_ONLY = (1 << 1),
1267+
1268+
/*
1269+
* Omit dangling symrefs from output; this only has an effect with
1270+
* INCLUDE_BROKEN, since they are otherwise not included at all.
1271+
*/
1272+
DO_FOR_EACH_OMIT_DANGLING_SYMREFS = (1 << 2),
1273+
1274+
/*
1275+
* Include root refs i.e. HEAD and pseudorefs along with the regular
1276+
* refs.
1277+
*/
1278+
DO_FOR_EACH_INCLUDE_ROOT_REFS = (1 << 3),
1279+
};
1280+
1281+
/*
1282+
* Return an iterator that goes over each reference in `refs` for
1283+
* which the refname begins with prefix. If trim is non-zero, then
1284+
* trim that many characters off the beginning of each refname.
1285+
* The output is ordered by refname.
1286+
*/
1287+
struct ref_iterator *refs_ref_iterator_begin(
1288+
struct ref_store *refs,
1289+
const char *prefix, const char **exclude_patterns,
1290+
int trim, enum do_for_each_ref_flags flags);
1291+
1292+
/*
1293+
* Advance the iterator to the first or next item and return ITER_OK.
1294+
* If the iteration is exhausted, free the resources associated with
1295+
* the ref_iterator and return ITER_DONE. On errors, free the iterator
1296+
* resources and return ITER_ERROR. It is a bug to use ref_iterator or
1297+
* call this function again after it has returned ITER_DONE or
1298+
* ITER_ERROR.
1299+
*/
1300+
int ref_iterator_advance(struct ref_iterator *ref_iterator);
1301+
1302+
/*
1303+
* Seek the iterator to the first reference with the given prefix.
1304+
* The prefix is matched as a literal string, without regard for path
1305+
* separators. If prefix is NULL or the empty string, seek the iterator to the
1306+
* first reference again.
1307+
*
1308+
* This function is expected to behave as if a new ref iterator with the same
1309+
* prefix had been created, but allows reuse of iterators and thus may allow
1310+
* the backend to optimize. Parameters other than the prefix that have been
1311+
* passed when creating the iterator will remain unchanged.
1312+
*
1313+
* Returns 0 on success, a negative error code otherwise.
1314+
*/
1315+
int ref_iterator_seek(struct ref_iterator *ref_iterator,
1316+
const char *prefix);
1317+
1318+
/*
1319+
* If possible, peel the reference currently being viewed by the
1320+
* iterator. Return 0 on success.
1321+
*/
1322+
int ref_iterator_peel(struct ref_iterator *ref_iterator,
1323+
struct object_id *peeled);
1324+
1325+
/* Free the reference iterator and any associated resources. */
1326+
void ref_iterator_free(struct ref_iterator *ref_iterator);
1327+
1328+
/*
1329+
* The common backend for the for_each_*ref* functions. Call fn for
1330+
* each reference in iter. If the iterator itself ever returns
1331+
* ITER_ERROR, return -1. If fn ever returns a non-zero value, stop
1332+
* the iteration and return that value. Otherwise, return 0. In any
1333+
* case, free the iterator when done. This function is basically an
1334+
* adapter between the callback style of reference iteration and the
1335+
* iterator style.
1336+
*/
1337+
int do_for_each_ref_iterator(struct ref_iterator *iter,
1338+
each_ref_fn fn, void *cb_data);
1339+
11931340
#endif /* REFS_H */

refs/refs-internal.h

Lines changed: 2 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -244,90 +244,8 @@ const char *find_descendant_ref(const char *dirname,
244244
#define SYMREF_MAXDEPTH 5
245245

246246
/*
247-
* These flags are passed to refs_ref_iterator_begin() (and do_for_each_ref(),
248-
* which feeds it).
249-
*/
250-
enum do_for_each_ref_flags {
251-
/*
252-
* Include broken references in a do_for_each_ref*() iteration, which
253-
* would normally be omitted. This includes both refs that point to
254-
* missing objects (a true repository corruption), ones with illegal
255-
* names (which we prefer not to expose to callers), as well as
256-
* dangling symbolic refs (i.e., those that point to a non-existent
257-
* ref; this is not a corruption, but as they have no valid oid, we
258-
* omit them from normal iteration results).
259-
*/
260-
DO_FOR_EACH_INCLUDE_BROKEN = (1 << 0),
261-
262-
/*
263-
* Only include per-worktree refs in a do_for_each_ref*() iteration.
264-
* Normally this will be used with a files ref_store, since that's
265-
* where all reference backends will presumably store their
266-
* per-worktree refs.
267-
*/
268-
DO_FOR_EACH_PER_WORKTREE_ONLY = (1 << 1),
269-
270-
/*
271-
* Omit dangling symrefs from output; this only has an effect with
272-
* INCLUDE_BROKEN, since they are otherwise not included at all.
273-
*/
274-
DO_FOR_EACH_OMIT_DANGLING_SYMREFS = (1 << 2),
275-
276-
/*
277-
* Include root refs i.e. HEAD and pseudorefs along with the regular
278-
* refs.
279-
*/
280-
DO_FOR_EACH_INCLUDE_ROOT_REFS = (1 << 3),
281-
};
282-
283-
/*
284-
* Reference iterators
285-
*
286-
* A reference iterator encapsulates the state of an in-progress
287-
* iteration over references. Create an instance of `struct
288-
* ref_iterator` via one of the functions in this module.
289-
*
290-
* A freshly-created ref_iterator doesn't yet point at a reference. To
291-
* advance the iterator, call ref_iterator_advance(). If successful,
292-
* this sets the iterator's refname, oid, and flags fields to describe
293-
* the next reference and returns ITER_OK. The data pointed at by
294-
* refname and oid belong to the iterator; if you want to retain them
295-
* after calling ref_iterator_advance() again or calling
296-
* ref_iterator_free(), you must make a copy. When the iteration has
297-
* been exhausted, ref_iterator_advance() releases any resources
298-
* associated with the iteration, frees the ref_iterator object, and
299-
* returns ITER_DONE. If you want to abort the iteration early, call
300-
* ref_iterator_free(), which also frees the ref_iterator object and
301-
* any associated resources. If there was an internal error advancing
302-
* to the next entry, ref_iterator_advance() aborts the iteration,
303-
* frees the ref_iterator, and returns ITER_ERROR.
304-
*
305-
* The reference currently being looked at can be peeled by calling
306-
* ref_iterator_peel(). This function is often faster than peel_ref(),
307-
* so it should be preferred when iterating over references.
308-
*
309-
* Putting it all together, a typical iteration looks like this:
310-
*
311-
* int ok;
312-
* struct ref_iterator *iter = ...;
313-
*
314-
* while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
315-
* if (want_to_stop_iteration()) {
316-
* ok = ITER_DONE;
317-
* break;
318-
* }
319-
*
320-
* // Access information about the current reference:
321-
* if (!(iter->flags & REF_ISSYMREF))
322-
* printf("%s is %s\n", iter->refname, oid_to_hex(iter->oid));
323-
*
324-
* // If you need to peel the reference:
325-
* ref_iterator_peel(iter, &oid);
326-
* }
327-
*
328-
* if (ok != ITER_DONE)
329-
* handle_error();
330-
* ref_iterator_free(iter);
247+
* Data structure for holding a reference iterator. See refs.h for
248+
* more details and usage instructions.
331249
*/
332250
struct ref_iterator {
333251
struct ref_iterator_vtable *vtable;
@@ -337,42 +255,6 @@ struct ref_iterator {
337255
unsigned int flags;
338256
};
339257

340-
/*
341-
* Advance the iterator to the first or next item and return ITER_OK.
342-
* If the iteration is exhausted, free the resources associated with
343-
* the ref_iterator and return ITER_DONE. On errors, free the iterator
344-
* resources and return ITER_ERROR. It is a bug to use ref_iterator or
345-
* call this function again after it has returned ITER_DONE or
346-
* ITER_ERROR.
347-
*/
348-
int ref_iterator_advance(struct ref_iterator *ref_iterator);
349-
350-
/*
351-
* Seek the iterator to the first reference with the given prefix.
352-
* The prefix is matched as a literal string, without regard for path
353-
* separators. If prefix is NULL or the empty string, seek the iterator to the
354-
* first reference again.
355-
*
356-
* This function is expected to behave as if a new ref iterator with the same
357-
* prefix had been created, but allows reuse of iterators and thus may allow
358-
* the backend to optimize. Parameters other than the prefix that have been
359-
* passed when creating the iterator will remain unchanged.
360-
*
361-
* Returns 0 on success, a negative error code otherwise.
362-
*/
363-
int ref_iterator_seek(struct ref_iterator *ref_iterator,
364-
const char *prefix);
365-
366-
/*
367-
* If possible, peel the reference currently being viewed by the
368-
* iterator. Return 0 on success.
369-
*/
370-
int ref_iterator_peel(struct ref_iterator *ref_iterator,
371-
struct object_id *peeled);
372-
373-
/* Free the reference iterator and any associated resources. */
374-
void ref_iterator_free(struct ref_iterator *ref_iterator);
375-
376258
/*
377259
* An iterator over nothing (its first ref_iterator_advance() call
378260
* returns ITER_DONE).
@@ -384,17 +266,6 @@ struct ref_iterator *empty_ref_iterator_begin(void);
384266
*/
385267
int is_empty_ref_iterator(struct ref_iterator *ref_iterator);
386268

387-
/*
388-
* Return an iterator that goes over each reference in `refs` for
389-
* which the refname begins with prefix. If trim is non-zero, then
390-
* trim that many characters off the beginning of each refname.
391-
* The output is ordered by refname.
392-
*/
393-
struct ref_iterator *refs_ref_iterator_begin(
394-
struct ref_store *refs,
395-
const char *prefix, const char **exclude_patterns,
396-
int trim, enum do_for_each_ref_flags flags);
397-
398269
/*
399270
* A callback function used to instruct merge_ref_iterator how to
400271
* interleave the entries from iter0 and iter1. The function should
@@ -520,18 +391,6 @@ struct ref_iterator_vtable {
520391
*/
521392
extern struct ref_iterator *current_ref_iter;
522393

523-
/*
524-
* The common backend for the for_each_*ref* functions. Call fn for
525-
* each reference in iter. If the iterator itself ever returns
526-
* ITER_ERROR, return -1. If fn ever returns a non-zero value, stop
527-
* the iteration and return that value. Otherwise, return 0. In any
528-
* case, free the iterator when done. This function is basically an
529-
* adapter between the callback style of reference iteration and the
530-
* iterator style.
531-
*/
532-
int do_for_each_ref_iterator(struct ref_iterator *iter,
533-
each_ref_fn fn, void *cb_data);
534-
535394
struct ref_store;
536395

537396
/* refs backends */

0 commit comments

Comments
 (0)