From aefcc9b367016581743e57adf667ee4d56691bb1 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 23 Feb 2026 12:59:40 +0100 Subject: refs: introduce `refs_for_each_ref_ext` In the refs subsystem we have a proliferation of functions that all iterate through references. (Almost) all of these functions internally call `do_for_each_ref()` and provide slightly different arguments so that one can control different aspects of its behaviour. This approach doesn't really scale: every time there is a slightly different use case for iterating through refs we create another new function. This combinatorial explosion doesn't make a lot of sense: it leads to confusing interfaces and heightens the maintenance burden. Refactor the code to become more composable by: - Exposing `do_for_each_ref()` as `refs_for_each_ref_ext()`. - Introducing an options structure that lets the caller control individual options. This gives us a much better foundation to build on going forward. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- refs.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'refs.h') diff --git a/refs.h b/refs.h index 5190e98b2c..bb9c64a51c 100644 --- a/refs.h +++ b/refs.h @@ -453,8 +453,37 @@ int refs_head_ref(struct ref_store *refs, int refs_head_ref_namespaced(struct ref_store *refs, refs_for_each_cb fn, void *cb_data); + +struct refs_for_each_ref_options { + /* Only iterate over references that have this given prefix. */ + const char *prefix; + + /* + * Exclude any references that match any of these patterns on a + * best-effort basis. The caller needs to be prepared for the exclude + * patterns to be ignored. + * + * The array must be terminated with a NULL sentinel value. + */ + const char **exclude_patterns; + + /* + * The number of bytes to trim from the refname. Note that the trimmed + * bytes must not cause the reference to become empty. As such, this + * field should typically only be set when one uses a `prefix` ending + * in a slash. + */ + size_t trim_prefix; + + /* Flags that change which refs will be included. */ + enum refs_for_each_flag flags; +}; + int refs_for_each_ref(struct ref_store *refs, refs_for_each_cb fn, void *cb_data); +int refs_for_each_ref_ext(struct ref_store *refs, + refs_for_each_cb cb, void *cb_data, + const struct refs_for_each_ref_options *opts); int refs_for_each_ref_in(struct ref_store *refs, const char *prefix, refs_for_each_cb fn, void *cb_data); int refs_for_each_tag_ref(struct ref_store *refs, -- cgit v1.3