aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2026-02-23 12:59:42 +0100
committerJunio C Hamano <gitster@pobox.com>2026-02-23 13:21:18 -0800
commit5387919327574b5067f7efd986fca8793c95c71a (patch)
tree60f3986308d658326c19f173a1d9da8022614715
parentdaf01b1366ca644d45374451560aeeb4fc8a7765 (diff)
downloadgit-5387919327574b5067f7efd986fca8793c95c71a.tar.xz
refs: generalize `refs_for_each_namespaced_ref()`
The function `refs_for_each_namespaced_ref()` iterates through all references that are part of the current ref namespace. This namespace can be configured by setting the `GIT_NAMESPACE` environment variable and is then retrieved by calling `get_git_namespace()`. If a namespace is configured, then we: - Obviously only yield refs that exist in this namespace. - Rewrite exclude patterns so that they work for the given namespace, if any namespace is currently configured. Port this logic to `refs_for_each_ref_ext()` by adding a new `namespace` field to the options structure. This gives callers more flexibility as they can decide by themselves whether they want to use the globally configured or an arbitrary other namespace. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--refs.c47
-rw-r--r--refs.h7
2 files changed, 36 insertions, 18 deletions
diff --git a/refs.c b/refs.c
index e4402d787f..0d0f0edbfb 100644
--- a/refs.c
+++ b/refs.c
@@ -1848,10 +1848,14 @@ 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)
{
+ struct strvec namespaced_exclude_patterns = STRVEC_INIT;
+ struct strbuf namespaced_prefix = STRBUF_INIT;
struct strbuf real_pattern = STRBUF_INIT;
struct for_each_ref_filter filter;
struct ref_iterator *iter;
size_t trim_prefix = opts->trim_prefix;
+ const char **exclude_patterns;
+ const char *prefix;
int ret;
if (!refs)
@@ -1886,11 +1890,29 @@ int refs_for_each_ref_ext(struct ref_store *refs,
cb_data = &filter;
}
- iter = refs_ref_iterator_begin(refs, opts->prefix ? opts->prefix : "",
- opts->exclude_patterns,
+ if (opts->namespace) {
+ strbuf_addstr(&namespaced_prefix, opts->namespace);
+ if (opts->prefix)
+ strbuf_addstr(&namespaced_prefix, opts->prefix);
+ else
+ strbuf_addstr(&namespaced_prefix, "refs/");
+
+ prefix = namespaced_prefix.buf;
+ exclude_patterns = get_namespaced_exclude_patterns(opts->exclude_patterns,
+ opts->namespace,
+ &namespaced_exclude_patterns);
+ } else {
+ prefix = opts->prefix ? opts->prefix : "";
+ exclude_patterns = opts->exclude_patterns;
+ }
+
+ iter = refs_ref_iterator_begin(refs, prefix, exclude_patterns,
trim_prefix, opts->flags);
ret = do_for_each_ref_iterator(iter, cb, cb_data);
+
+ strvec_clear(&namespaced_exclude_patterns);
+ strbuf_release(&namespaced_prefix);
strbuf_release(&real_pattern);
return ret;
}
@@ -1937,22 +1959,11 @@ int refs_for_each_namespaced_ref(struct ref_store *refs,
const char **exclude_patterns,
refs_for_each_cb cb, void *cb_data)
{
- struct refs_for_each_ref_options opts = { 0 };
- struct strvec namespaced_exclude_patterns = STRVEC_INIT;
- struct strbuf prefix = STRBUF_INIT;
- int ret;
-
- opts.exclude_patterns = get_namespaced_exclude_patterns(exclude_patterns,
- get_git_namespace(),
- &namespaced_exclude_patterns);
- strbuf_addf(&prefix, "%srefs/", get_git_namespace());
- opts.prefix = prefix.buf;
-
- ret = refs_for_each_ref_ext(refs, cb, cb_data, &opts);
-
- strvec_clear(&namespaced_exclude_patterns);
- strbuf_release(&prefix);
- return ret;
+ struct refs_for_each_ref_options opts = {
+ .exclude_patterns = exclude_patterns,
+ .namespace = get_git_namespace(),
+ };
+ return refs_for_each_ref_ext(refs, cb, cb_data, &opts);
}
int refs_for_each_rawref(struct ref_store *refs, refs_for_each_cb fn, void *cb_data)
diff --git a/refs.h b/refs.h
index a66dbf3865..5a5fb4e1e4 100644
--- a/refs.h
+++ b/refs.h
@@ -469,6 +469,13 @@ struct refs_for_each_ref_options {
const char *pattern;
/*
+ * If set, only yield refs part of the configured namespace. Exclude
+ * patterns will be rewritten to apply to the namespace, and the prefix
+ * will be considered relative to the namespace.
+ */
+ const char *namespace;
+
+ /*
* 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.