remote: move remote group resolution to remote.c

`get_remote_group`, `add_remote_or_group`, and the `remote_group_data` struct are currently defined as static helpers inside builtin/fetch.c. They implement generic remote group resolution that is not specific to fetch — they parse `remotes.<name>` config entries and resolve a name to either a list of group members or a single configured remote. Move them to remote.c and declare them in remote.h so that other builtins can use the same logic without duplication. Useful for the next patch. Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Usman Akinyemi committed May 3, 2026 at 21:04 UTC 3e7b9dce27b1519f6745c89fe01f0b840acddb0a
3 files changed +49 -42
builtin/fetch.c
-42
@@ -2138,48 +2138,6 @@ static int get_one_remote_for_fetch(struct remote *remote, void *priv)
2138 return 0;
2139 }
2140
2141 -struct remote_group_data {
2142 - const char *name;
2143 - struct string_list *list;
2144 -};
2145 -
2146 -static int get_remote_group(const char *key, const char *value,
2147 - const struct config_context *ctx UNUSED,
2148 - void *priv)
2149 -{
2150 - struct remote_group_data *g = priv;
2151 -
2152 - if (skip_prefix(key, "remotes.", &key) && !strcmp(key, g->name)) {
2153 - /* split list by white space */
2154 - while (*value) {
2155 - size_t wordlen = strcspn(value, " \t\n");
2156 -
2157 - if (wordlen >= 1)
2158 - string_list_append_nodup(g->list,
2159 - xstrndup(value, wordlen));
2160 - value += wordlen + (value[wordlen] != '\0');
2161 - }
2162 - }
2163 -
2164 - return 0;
2165 -}
2166 -
2167 -static int add_remote_or_group(const char *name, struct string_list *list)
2168 -{
2169 - int prev_nr = list->nr;
2170 - struct remote_group_data g;
2171 - g.name = name; g.list = list;
2172 -
2173 - repo_config(the_repository, get_remote_group, &g);
2174 - if (list->nr == prev_nr) {
2175 - struct remote *remote = remote_get(name);
2176 - if (!remote_is_configured(remote, 0))
2177 - return 0;
2178 - string_list_append(list, remote->name);
2179 - }
2180 - return 1;
2181 -}
2182 -
2141 static void add_options_to_argv(struct strvec *argv,
2142 const struct fetch_config *config)
2143 {
remote.c
+37
@@ -2114,6 +2114,43 @@ int get_fetch_map(const struct ref *remote_refs,
2114 return 0;
2115 }
2116
2117 +int get_remote_group(const char *key, const char *value,
2118 + const struct config_context *ctx UNUSED,
2119 + void *priv)
2120 +{
2121 + struct remote_group_data *g = priv;
2122 +
2123 + if (skip_prefix(key, "remotes.", &key) && !strcmp(key, g->name)) {
2124 + /* split list by white space */
2125 + while (*value) {
2126 + size_t wordlen = strcspn(value, " \t\n");
2127 +
2128 + if (wordlen >= 1)
2129 + string_list_append_nodup(g->list,
2130 + xstrndup(value, wordlen));
2131 + value += wordlen + (value[wordlen] != '\0');
2132 + }
2133 + }
2134 +
2135 + return 0;
2136 +}
2137 +
2138 +int add_remote_or_group(const char *name, struct string_list *list)
2139 +{
2140 + int prev_nr = list->nr;
2141 + struct remote_group_data g;
2142 + g.name = name; g.list = list;
2143 +
2144 + repo_config(the_repository, get_remote_group, &g);
2145 + if (list->nr == prev_nr) {
2146 + struct remote *remote = remote_get(name);
2147 + if (!remote_is_configured(remote, 0))
2148 + return 0;
2149 + string_list_append(list, remote->name);
2150 + }
2151 + return 1;
2152 +}
2153 +
2154 int resolve_remote_symref(struct ref *ref, struct ref *list)
2155 {
2156 if (!ref->symref)
remote.h
+12
@@ -347,6 +347,18 @@ int branch_has_merge_config(struct branch *branch);
347
348 int branch_merge_matches(struct branch *, int n, const char *);
349
350 +/* list of the remote in a group as configured */
351 +struct remote_group_data {
352 + const char *name;
353 + struct string_list *list;
354 +};
355 +
356 +int get_remote_group(const char *key, const char *value,
357 + const struct config_context *ctx,
358 + void *priv);
359 +
360 +int add_remote_or_group(const char *name, struct string_list *list);
361 +
362 /**
363 * Return the fully-qualified refname of the tracking branch for `branch`.
364 * I.e., what "branch@{upstream}" would give you. Returns NULL if no