summaryrefslogtreecommitdiff
path: root/refs.c
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2025-10-23 09:16:10 +0200
committerJunio C Hamano <gitster@pobox.com>2025-11-04 07:32:24 -0800
commitbdbebe5714b25dc9d215b48efbb80f410925d7dd (patch)
tree4717bd456f36f6927c4c9aa31fdc0bea1c29c709 /refs.c
parentf2bf477c7e05ebc9541c708d11b616bf1a2a9105 (diff)
refs: introduce wrapper struct for `each_ref_fn`
The `each_ref_fn` callback function type is used across our code base for several different functions that iterate through reference. There's a bunch of callbacks implementing this type, which makes any changes to the callback signature extremely noisy. An example of the required churn is e8207717f1 (refs: add referent to each_ref_fn, 2024-08-09): adding a single argument required us to change 48 files. It was already proposed back then [1] that we might want to introduce a wrapper structure to alleviate the pain going forward. While this of course requires the same kind of global refactoring as just introducing a new parameter, it at least allows us to more change the callback type afterwards by just extending the wrapper structure. One counterargument to this refactoring is that it makes the structure more opaque. While it is obvious which callsites need to be fixed up when we change the function type, it's not obvious anymore once we use a structure. That being said, we only have a handful of sites that actually need to populate this wrapper structure: our ref backends, "refs/iterator.c" as well as very few sites that invoke the iterator callback functions directly. Introduce this wrapper structure so that we can adapt the iterator interfaces more readily. [1]: <ZmarVcF5JjsZx0dl@tanuki> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c67
1 files changed, 38 insertions, 29 deletions
diff --git a/refs.c b/refs.c
index 965381367e..25f0579d61 100644
--- a/refs.c
+++ b/refs.c
@@ -426,17 +426,19 @@ int refs_ref_exists(struct ref_store *refs, const char *refname)
NULL, NULL);
}
-static int for_each_filter_refs(const char *refname, const char *referent,
- const struct object_id *oid,
- int flags, void *data)
+static int for_each_filter_refs(const struct reference *ref, void *data)
{
struct for_each_ref_filter *filter = data;
- if (wildmatch(filter->pattern, refname, 0))
+ if (wildmatch(filter->pattern, ref->name, 0))
return 0;
- if (filter->prefix)
- skip_prefix(refname, filter->prefix, &refname);
- return filter->fn(refname, referent, oid, flags, filter->cb_data);
+ if (filter->prefix) {
+ struct reference skipped = *ref;
+ skip_prefix(skipped.name, filter->prefix, &skipped.name);
+ return filter->fn(&skipped, filter->cb_data);
+ } else {
+ return filter->fn(ref, filter->cb_data);
+ }
}
struct warn_if_dangling_data {
@@ -447,17 +449,15 @@ struct warn_if_dangling_data {
int dry_run;
};
-static int warn_if_dangling_symref(const char *refname, const char *referent UNUSED,
- const struct object_id *oid UNUSED,
- int flags, void *cb_data)
+static int warn_if_dangling_symref(const struct reference *ref, void *cb_data)
{
struct warn_if_dangling_data *d = cb_data;
const char *resolves_to, *msg;
- if (!(flags & REF_ISSYMREF))
+ if (!(ref->flags & REF_ISSYMREF))
return 0;
- resolves_to = refs_resolve_ref_unsafe(d->refs, refname, 0, NULL, NULL);
+ resolves_to = refs_resolve_ref_unsafe(d->refs, ref->name, 0, NULL, NULL);
if (!resolves_to
|| !string_list_has_string(d->refnames, resolves_to)) {
return 0;
@@ -466,7 +466,7 @@ static int warn_if_dangling_symref(const char *refname, const char *referent UNU
msg = d->dry_run
? _("%s%s will become dangling after %s is deleted\n")
: _("%s%s has become dangling after %s was deleted\n");
- fprintf(d->fp, msg, d->indent, refname, resolves_to);
+ fprintf(d->fp, msg, d->indent, ref->name, resolves_to);
return 0;
}
@@ -507,8 +507,15 @@ int refs_head_ref_namespaced(struct ref_store *refs, each_ref_fn fn, void *cb_da
int flag;
strbuf_addf(&buf, "%sHEAD", get_git_namespace());
- if (!refs_read_ref_full(refs, buf.buf, RESOLVE_REF_READING, &oid, &flag))
- ret = fn(buf.buf, NULL, &oid, flag, cb_data);
+ if (!refs_read_ref_full(refs, buf.buf, RESOLVE_REF_READING, &oid, &flag)) {
+ struct reference ref = {
+ .name = buf.buf,
+ .oid = &oid,
+ .flags = flag,
+ };
+
+ ret = fn(&ref, cb_data);
+ }
strbuf_release(&buf);
return ret;
@@ -1741,8 +1748,15 @@ int refs_head_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
int flag;
if (refs_resolve_ref_unsafe(refs, "HEAD", RESOLVE_REF_READING,
- &oid, &flag))
- return fn("HEAD", NULL, &oid, flag, cb_data);
+ &oid, &flag)) {
+ struct reference ref = {
+ .name = "HEAD",
+ .oid = &oid,
+ .flags = flag,
+ };
+
+ return fn(&ref, cb_data);
+ }
return 0;
}
@@ -2753,14 +2767,10 @@ struct do_for_each_reflog_help {
void *cb_data;
};
-static int do_for_each_reflog_helper(const char *refname,
- const char *referent UNUSED,
- const struct object_id *oid UNUSED,
- int flags UNUSED,
- void *cb_data)
+static int do_for_each_reflog_helper(const struct reference *ref, void *cb_data)
{
struct do_for_each_reflog_help *hp = cb_data;
- return hp->fn(refname, hp->cb_data);
+ return hp->fn(ref->name, hp->cb_data);
}
int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_data)
@@ -2976,25 +2986,24 @@ struct migration_data {
uint64_t index;
};
-static int migrate_one_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid,
- int flags, void *cb_data)
+static int migrate_one_ref(const struct reference *ref, void *cb_data)
{
struct migration_data *data = cb_data;
struct strbuf symref_target = STRBUF_INIT;
int ret;
- if (flags & REF_ISSYMREF) {
- ret = refs_read_symbolic_ref(data->old_refs, refname, &symref_target);
+ if (ref->flags & REF_ISSYMREF) {
+ ret = refs_read_symbolic_ref(data->old_refs, ref->name, &symref_target);
if (ret < 0)
goto done;
- ret = ref_transaction_update(data->transaction, refname, NULL, null_oid(the_hash_algo),
+ ret = ref_transaction_update(data->transaction, ref->name, NULL, null_oid(the_hash_algo),
symref_target.buf, NULL,
REF_SKIP_CREATE_REFLOG | REF_NO_DEREF, NULL, data->errbuf);
if (ret < 0)
goto done;
} else {
- ret = ref_transaction_create(data->transaction, refname, oid, NULL,
+ ret = ref_transaction_create(data->transaction, ref->name, ref->oid, NULL,
REF_SKIP_CREATE_REFLOG | REF_SKIP_OID_VERIFICATION,
NULL, data->errbuf);
if (ret < 0)