mirror of
https://github.com/git/git.git
synced 2026-01-09 01:34:00 +00:00
Merge branch 'kn/for-each-ref-skip'
"git for-each-ref" learns "--start-after" option to help applications that want to page its output. * kn/for-each-ref-skip: ref-cache: set prefix_state when seeking for-each-ref: introduce a '--start-after' option ref-filter: remove unnecessary else clause refs: selectively set prefix in the seek functions ref-cache: remove unused function 'find_ref_entry()' refs: expose `ref_iterator` via 'refs.h'
This commit is contained in:
155
refs.h
155
refs.h
@@ -1194,4 +1194,159 @@ int repo_migrate_ref_storage_format(struct repository *repo,
|
||||
unsigned int flags,
|
||||
struct strbuf *err);
|
||||
|
||||
/*
|
||||
* Reference iterators
|
||||
*
|
||||
* A reference iterator encapsulates the state of an in-progress
|
||||
* iteration over references. Create an instance of `struct
|
||||
* ref_iterator` via one of the functions in this module.
|
||||
*
|
||||
* A freshly-created ref_iterator doesn't yet point at a reference. To
|
||||
* advance the iterator, call ref_iterator_advance(). If successful,
|
||||
* this sets the iterator's refname, oid, and flags fields to describe
|
||||
* the next reference and returns ITER_OK. The data pointed at by
|
||||
* refname and oid belong to the iterator; if you want to retain them
|
||||
* after calling ref_iterator_advance() again or calling
|
||||
* ref_iterator_free(), you must make a copy. When the iteration has
|
||||
* been exhausted, ref_iterator_advance() releases any resources
|
||||
* associated with the iteration, frees the ref_iterator object, and
|
||||
* returns ITER_DONE. If you want to abort the iteration early, call
|
||||
* ref_iterator_free(), which also frees the ref_iterator object and
|
||||
* any associated resources. If there was an internal error advancing
|
||||
* to the next entry, ref_iterator_advance() aborts the iteration,
|
||||
* frees the ref_iterator, and returns ITER_ERROR.
|
||||
*
|
||||
* The reference currently being looked at can be peeled by calling
|
||||
* ref_iterator_peel(). This function is often faster than peel_ref(),
|
||||
* so it should be preferred when iterating over references.
|
||||
*
|
||||
* Putting it all together, a typical iteration looks like this:
|
||||
*
|
||||
* int ok;
|
||||
* struct ref_iterator *iter = ...;
|
||||
*
|
||||
* while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
|
||||
* if (want_to_stop_iteration()) {
|
||||
* ok = ITER_DONE;
|
||||
* break;
|
||||
* }
|
||||
*
|
||||
* // Access information about the current reference:
|
||||
* if (!(iter->flags & REF_ISSYMREF))
|
||||
* printf("%s is %s\n", iter->refname, oid_to_hex(iter->oid));
|
||||
*
|
||||
* // If you need to peel the reference:
|
||||
* ref_iterator_peel(iter, &oid);
|
||||
* }
|
||||
*
|
||||
* if (ok != ITER_DONE)
|
||||
* handle_error();
|
||||
* ref_iterator_free(iter);
|
||||
*/
|
||||
struct ref_iterator;
|
||||
|
||||
/*
|
||||
* These flags are passed to refs_ref_iterator_begin() (and do_for_each_ref(),
|
||||
* which feeds it).
|
||||
*/
|
||||
enum do_for_each_ref_flags {
|
||||
/*
|
||||
* Include broken references in a do_for_each_ref*() iteration, which
|
||||
* would normally be omitted. This includes both refs that point to
|
||||
* missing objects (a true repository corruption), ones with illegal
|
||||
* names (which we prefer not to expose to callers), as well as
|
||||
* dangling symbolic refs (i.e., those that point to a non-existent
|
||||
* ref; this is not a corruption, but as they have no valid oid, we
|
||||
* omit them from normal iteration results).
|
||||
*/
|
||||
DO_FOR_EACH_INCLUDE_BROKEN = (1 << 0),
|
||||
|
||||
/*
|
||||
* Only include per-worktree refs in a do_for_each_ref*() iteration.
|
||||
* Normally this will be used with a files ref_store, since that's
|
||||
* where all reference backends will presumably store their
|
||||
* per-worktree refs.
|
||||
*/
|
||||
DO_FOR_EACH_PER_WORKTREE_ONLY = (1 << 1),
|
||||
|
||||
/*
|
||||
* Omit dangling symrefs from output; this only has an effect with
|
||||
* INCLUDE_BROKEN, since they are otherwise not included at all.
|
||||
*/
|
||||
DO_FOR_EACH_OMIT_DANGLING_SYMREFS = (1 << 2),
|
||||
|
||||
/*
|
||||
* Include root refs i.e. HEAD and pseudorefs along with the regular
|
||||
* refs.
|
||||
*/
|
||||
DO_FOR_EACH_INCLUDE_ROOT_REFS = (1 << 3),
|
||||
};
|
||||
|
||||
/*
|
||||
* Return an iterator that goes over each reference in `refs` for
|
||||
* which the refname begins with prefix. If trim is non-zero, then
|
||||
* trim that many characters off the beginning of each refname.
|
||||
* The output is ordered by refname.
|
||||
*/
|
||||
struct ref_iterator *refs_ref_iterator_begin(
|
||||
struct ref_store *refs,
|
||||
const char *prefix, const char **exclude_patterns,
|
||||
int trim, enum do_for_each_ref_flags flags);
|
||||
|
||||
/*
|
||||
* Advance the iterator to the first or next item and return ITER_OK.
|
||||
* If the iteration is exhausted, free the resources associated with
|
||||
* the ref_iterator and return ITER_DONE. On errors, free the iterator
|
||||
* resources and return ITER_ERROR. It is a bug to use ref_iterator or
|
||||
* call this function again after it has returned ITER_DONE or
|
||||
* ITER_ERROR.
|
||||
*/
|
||||
int ref_iterator_advance(struct ref_iterator *ref_iterator);
|
||||
|
||||
enum ref_iterator_seek_flag {
|
||||
/*
|
||||
* When the REF_ITERATOR_SEEK_SET_PREFIX flag is set, the iterator's prefix is
|
||||
* updated to match the provided string, affecting all subsequent iterations. If
|
||||
* not, the iterator seeks to the specified reference and clears any previously
|
||||
* set prefix.
|
||||
*/
|
||||
REF_ITERATOR_SEEK_SET_PREFIX = (1 << 0),
|
||||
};
|
||||
|
||||
/*
|
||||
* Seek the iterator to the first reference matching the given seek string.
|
||||
* The seek string is matched as a literal string, without regard for path
|
||||
* separators. If seek is NULL or the empty string, seek the iterator to the
|
||||
* first reference again.
|
||||
*
|
||||
* This function is expected to behave as if a new ref iterator has been
|
||||
* created, but allows reuse of existing iterators for optimization.
|
||||
*
|
||||
* Returns 0 on success, a negative error code otherwise.
|
||||
*/
|
||||
int ref_iterator_seek(struct ref_iterator *ref_iterator, const char *refname,
|
||||
unsigned int flags);
|
||||
|
||||
/*
|
||||
* If possible, peel the reference currently being viewed by the
|
||||
* iterator. Return 0 on success.
|
||||
*/
|
||||
int ref_iterator_peel(struct ref_iterator *ref_iterator,
|
||||
struct object_id *peeled);
|
||||
|
||||
/* Free the reference iterator and any associated resources. */
|
||||
void ref_iterator_free(struct ref_iterator *ref_iterator);
|
||||
|
||||
/*
|
||||
* The common backend for the for_each_*ref* functions. Call fn for
|
||||
* each reference in iter. If the iterator itself ever returns
|
||||
* ITER_ERROR, return -1. If fn ever returns a non-zero value, stop
|
||||
* the iteration and return that value. Otherwise, return 0. In any
|
||||
* case, free the iterator when done. This function is basically an
|
||||
* adapter between the callback style of reference iteration and the
|
||||
* iterator style.
|
||||
*/
|
||||
int do_for_each_ref_iterator(struct ref_iterator *iter,
|
||||
each_ref_fn fn, void *cb_data);
|
||||
|
||||
#endif /* REFS_H */
|
||||
|
||||
Reference in New Issue
Block a user