refs: convert iteration over replace refs to accept ref store

The function `for_each_replace_ref()` is a bit of an oddball across the refs interfaces as it accepts a pointer to the repository instead of a pointer to the ref store. The only reason for us to accept a repository is so that we can eventually pass it back to the callback function that the caller has provided. This is somewhat arbitrary though, as callers that need the repository can instead make it accessible via the callback payload. Refactor the function to instead accept the ref store and adjust callers accordingly. This allows us to get rid of some of the boilerplate that we had to carry to pass along the repository and brings us in line with the other functions that iterate through refs. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed May 17, 2024 at 10:18 UTC 8378c9d27bace61d3fb238259604045a8997387b
6 files changed +28 -81
builtin/replace.c
+8 -5
@@ -43,11 +43,12 @@ enum replace_format {
43 };
44
45 struct show_data {
46 + struct repository *repo;
47 const char *pattern;
48 enum replace_format format;
49 };
50
50 -static int show_reference(struct repository *r, const char *refname,
51 +static int show_reference(const char *refname,
52 const struct object_id *oid,
53 int flag UNUSED, void *cb_data)
54 {
@@ -62,11 +63,11 @@ static int show_reference(struct repository *r, const char *refname,
63 struct object_id object;
64 enum object_type obj_type, repl_type;
65
65 - if (repo_get_oid(r, refname, &object))
66 + if (repo_get_oid(data->repo, refname, &object))
67 return error(_("failed to resolve '%s' as a valid ref"), refname);
68
68 - obj_type = oid_object_info(r, &object, NULL);
69 - repl_type = oid_object_info(r, oid, NULL);
69 + obj_type = oid_object_info(data->repo, &object, NULL);
70 + repl_type = oid_object_info(data->repo, oid, NULL);
71
72 printf("%s (%s) -> %s (%s)\n", refname, type_name(obj_type),
73 oid_to_hex(oid), type_name(repl_type));
@@ -80,6 +81,7 @@ static int list_replace_refs(const char *pattern, const char *format)
81 {
82 struct show_data data;
83
84 + data.repo = the_repository;
85 if (!pattern)
86 pattern = "*";
87 data.pattern = pattern;
@@ -99,7 +101,8 @@ static int list_replace_refs(const char *pattern, const char *format)
101 "valid formats are 'short', 'medium' and 'long'"),
102 format);
103
102 - for_each_replace_ref(the_repository, show_reference, (void *)&data);
104 + refs_for_each_replace_ref(get_main_ref_store(the_repository),
105 + show_reference, (void *)&data);
106
107 return 0;
108 }
refs.c
+7 -51
@@ -1576,53 +1576,12 @@ struct ref_iterator *refs_ref_iterator_begin(
1576 return iter;
1577 }
1578
1579 -/*
1580 - * Call fn for each reference in the specified submodule for which the
1581 - * refname begins with prefix. If trim is non-zero, then trim that
1582 - * many characters off the beginning of each refname before passing
1583 - * the refname to fn. flags can be DO_FOR_EACH_INCLUDE_BROKEN to
1584 - * include broken references in the iteration. If fn ever returns a
1585 - * non-zero value, stop the iteration and return that value;
1586 - * otherwise, return 0.
1587 - */
1588 -static int do_for_each_repo_ref(struct repository *r, const char *prefix,
1589 - each_repo_ref_fn fn, int trim, int flags,
1590 - void *cb_data)
1591 -{
1592 - struct ref_iterator *iter;
1593 - struct ref_store *refs = get_main_ref_store(r);
1594 -
1595 - if (!refs)
1596 - return 0;
1597 -
1598 - iter = refs_ref_iterator_begin(refs, prefix, NULL, trim, flags);
1599 -
1600 - return do_for_each_repo_ref_iterator(r, iter, fn, cb_data);
1601 -}
1602 -
1603 -struct do_for_each_ref_help {
1604 - each_ref_fn *fn;
1605 - void *cb_data;
1606 -};
1607 -
1608 -static int do_for_each_ref_helper(struct repository *r UNUSED,
1609 - const char *refname,
1610 - const struct object_id *oid,
1611 - int flags,
1612 - void *cb_data)
1613 -{
1614 - struct do_for_each_ref_help *hp = cb_data;
1615 -
1616 - return hp->fn(refname, oid, flags, hp->cb_data);
1617 -}
1618 -
1579 static int do_for_each_ref(struct ref_store *refs, const char *prefix,
1580 const char **exclude_patterns,
1581 each_ref_fn fn, int trim,
1582 enum do_for_each_ref_flags flags, void *cb_data)
1583 {
1584 struct ref_iterator *iter;
1625 - struct do_for_each_ref_help hp = { fn, cb_data };
1585
1586 if (!refs)
1587 return 0;
@@ -1630,8 +1589,7 @@ static int do_for_each_ref(struct ref_store *refs, const char *prefix,
1589 iter = refs_ref_iterator_begin(refs, prefix, exclude_patterns, trim,
1590 flags);
1591
1633 - return do_for_each_repo_ref_iterator(the_repository, iter,
1634 - do_for_each_ref_helper, &hp);
1592 + return do_for_each_ref_iterator(iter, fn, cb_data);
1593 }
1594
1595 int refs_for_each_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
@@ -1652,12 +1610,12 @@ int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix,
1610 return do_for_each_ref(refs, prefix, exclude_patterns, fn, 0, 0, cb_data);
1611 }
1612
1655 -int for_each_replace_ref(struct repository *r, each_repo_ref_fn fn, void *cb_data)
1613 +int refs_for_each_replace_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
1614 {
1615 const char *git_replace_ref_base = ref_namespace[NAMESPACE_REPLACE].ref;
1658 - return do_for_each_repo_ref(r, git_replace_ref_base, fn,
1659 - strlen(git_replace_ref_base),
1660 - DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
1616 + return do_for_each_ref(refs, git_replace_ref_base, NULL, fn,
1617 + strlen(git_replace_ref_base),
1618 + DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
1619 }
1620
1621 int refs_for_each_namespaced_ref(struct ref_store *refs,
@@ -2425,8 +2383,7 @@ struct do_for_each_reflog_help {
2383 void *cb_data;
2384 };
2385
2428 -static int do_for_each_reflog_helper(struct repository *r UNUSED,
2429 - const char *refname,
2386 +static int do_for_each_reflog_helper(const char *refname,
2387 const struct object_id *oid UNUSED,
2388 int flags,
2389 void *cb_data)
@@ -2442,8 +2399,7 @@ int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_dat
2399
2400 iter = refs->be->reflog_iterator_begin(refs);
2401
2445 - return do_for_each_repo_ref_iterator(the_repository, iter,
2446 - do_for_each_reflog_helper, &hp);
2402 + return do_for_each_ref_iterator(iter, do_for_each_reflog_helper, &hp);
2403 }
2404
2405 int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
refs.h
+2 -15
@@ -298,16 +298,6 @@ struct ref_transaction;
298 typedef int each_ref_fn(const char *refname,
299 const struct object_id *oid, int flags, void *cb_data);
300
301 -/*
302 - * The same as each_ref_fn, but also with a repository argument that
303 - * contains the repository associated with the callback.
304 - */
305 -typedef int each_repo_ref_fn(struct repository *r,
306 - const char *refname,
307 - const struct object_id *oid,
308 - int flags,
309 - void *cb_data);
310 -
301 /*
302 * The following functions invoke the specified callback function for
303 * each reference indicated. If the function ever returns a nonzero
@@ -329,6 +319,8 @@ int refs_for_each_branch_ref(struct ref_store *refs,
319 each_ref_fn fn, void *cb_data);
320 int refs_for_each_remote_ref(struct ref_store *refs,
321 each_ref_fn fn, void *cb_data);
322 +int refs_for_each_replace_ref(struct ref_store *refs,
323 + each_ref_fn fn, void *cb_data);
324
325 /*
326 * references matching any pattern in "exclude_patterns" are omitted from the
@@ -353,11 +345,6 @@ int refs_for_each_fullref_in_prefixes(struct ref_store *refs,
345 const char **exclude_patterns,
346 each_ref_fn fn, void *cb_data);
347
356 -/**
357 - * iterate refs from the respective area.
358 - */
359 -int for_each_replace_ref(struct repository *r, each_repo_ref_fn fn, void *cb_data);
360 -
348 /* iterates all refs that match the specified glob pattern. */
349 int refs_for_each_glob_ref(struct ref_store *refs, each_ref_fn fn,
350 const char *pattern, void *cb_data);
refs/iterator.c
+3 -3
@@ -440,15 +440,15 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
440
441 struct ref_iterator *current_ref_iter = NULL;
442
443 -int do_for_each_repo_ref_iterator(struct repository *r, struct ref_iterator *iter,
444 - each_repo_ref_fn fn, void *cb_data)
443 +int do_for_each_ref_iterator(struct ref_iterator *iter,
444 + each_ref_fn fn, void *cb_data)
445 {
446 int retval = 0, ok;
447 struct ref_iterator *old_ref_iter = current_ref_iter;
448
449 current_ref_iter = iter;
450 while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
451 - retval = fn(r, iter->refname, iter->oid, iter->flags, cb_data);
451 + retval = fn(iter->refname, iter->oid, iter->flags, cb_data);
452 if (retval) {
453 /*
454 * If ref_iterator_abort() returns ITER_ERROR,
refs/refs-internal.h
+2 -3
@@ -503,9 +503,8 @@ extern struct ref_iterator *current_ref_iter;
503 * adapter between the callback style of reference iteration and the
504 * iterator style.
505 */
506 -int do_for_each_repo_ref_iterator(struct repository *r,
507 - struct ref_iterator *iter,
508 - each_repo_ref_fn fn, void *cb_data);
506 +int do_for_each_ref_iterator(struct ref_iterator *iter,
507 + each_ref_fn fn, void *cb_data);
508
509 struct ref_store;
510
replace-object.c
+6 -4
@@ -8,12 +8,13 @@
8 #include "repository.h"
9 #include "commit.h"
10
11 -static int register_replace_ref(struct repository *r,
12 - const char *refname,
11 +static int register_replace_ref(const char *refname,
12 const struct object_id *oid,
13 int flag UNUSED,
15 - void *cb_data UNUSED)
14 + void *cb_data)
15 {
16 + struct repository *r = cb_data;
17 +
18 /* Get sha1 from refname */
19 const char *slash = strrchr(refname, '/');
20 const char *hash = slash ? slash + 1 : refname;
@@ -50,7 +51,8 @@ void prepare_replace_object(struct repository *r)
51 xmalloc(sizeof(*r->objects->replace_map));
52 oidmap_init(r->objects->replace_map, 0);
53
53 - for_each_replace_ref(r, register_replace_ref, NULL);
54 + refs_for_each_replace_ref(get_main_ref_store(r),
55 + register_replace_ref, r);
56 r->objects->replace_map_initialized = 1;
57
58 pthread_mutex_unlock(&r->objects->replace_mutex);