fetch: make filter_options local to cmd_fetch()

The `struct list_objects_filter_options filter_options` variable used in "builtin/fetch.c" to store the parsed filters specified by `--filter=<filterspec>` is currently a static variable global to the file. As we are going to use it more in a following commit, it could become a bit less easy to understand how it's managed. To avoid that, let's make it clear that it's owned by cmd_fetch() by moving its definition into that function and making it non-static. This requires passing a pointer to it through the prepare_transport(), do_fetch(), backfill_tags(), fetch_one_setup_partial(), and fetch_one() functions, but it's quite straightforward. Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Christian Couder committed Feb 16, 2026 at 14:23 UTC f7565410e1f803873c097258109ff0258ad913fc
1 file changed +27 -21
builtin/fetch.c
+27 -21
@@ -97,7 +97,6 @@ static struct strbuf default_rla = STRBUF_INIT;
97 static struct transport *gtransport;
98 static struct transport *gsecondary;
99 static struct refspec refmap = REFSPEC_INIT_FETCH;
100 -static struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT;
100 static struct string_list server_options = STRING_LIST_INIT_DUP;
101 static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
102
@@ -1562,7 +1561,8 @@ static void add_negotiation_tips(struct git_transport_options *smart_options)
1561 smart_options->negotiation_tips = oids;
1562 }
1563
1565 -static struct transport *prepare_transport(struct remote *remote, int deepen)
1564 +static struct transport *prepare_transport(struct remote *remote, int deepen,
1565 + struct list_objects_filter_options *filter_options)
1566 {
1567 struct transport *transport;
1568
@@ -1586,9 +1586,9 @@ static struct transport *prepare_transport(struct remote *remote, int deepen)
1586 set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
1587 if (refetch)
1588 set_option(transport, TRANS_OPT_REFETCH, "yes");
1589 - if (filter_options.choice) {
1589 + if (filter_options->choice) {
1590 const char *spec =
1591 - expand_list_objects_filter_spec(&filter_options);
1591 + expand_list_objects_filter_spec(filter_options);
1592 set_option(transport, TRANS_OPT_LIST_OBJECTS_FILTER, spec);
1593 set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
1594 }
@@ -1607,7 +1607,8 @@ static int backfill_tags(struct display_state *display_state,
1607 struct ref *ref_map,
1608 struct fetch_head *fetch_head,
1609 const struct fetch_config *config,
1610 - struct ref_update_display_info_array *display_array)
1610 + struct ref_update_display_info_array *display_array,
1611 + struct list_objects_filter_options *filter_options)
1612 {
1613 int retcode, cannot_reuse;
1614
@@ -1621,7 +1622,7 @@ static int backfill_tags(struct display_state *display_state,
1622 cannot_reuse = transport->cannot_reuse ||
1623 deepen_since || deepen_not.nr;
1624 if (cannot_reuse) {
1624 - gsecondary = prepare_transport(transport->remote, 0);
1625 + gsecondary = prepare_transport(transport->remote, 0, filter_options);
1626 transport = gsecondary;
1627 }
1628
@@ -1834,7 +1835,8 @@ out:
1835
1836 static int do_fetch(struct transport *transport,
1837 struct refspec *rs,
1837 - const struct fetch_config *config)
1838 + const struct fetch_config *config,
1839 + struct list_objects_filter_options *filter_options)
1840 {
1841 struct ref_transaction *transaction = NULL;
1842 struct ref *ref_map = NULL;
@@ -1997,7 +1999,7 @@ static int do_fetch(struct transport *transport,
1999 * the transaction and don't commit anything.
2000 */
2001 if (backfill_tags(&display_state, transport, transaction, tags_ref_map,
2000 - &fetch_head, config, &display_array))
2002 + &fetch_head, config, &display_array, filter_options))
2003 retcode = 1;
2004 }
2005
@@ -2339,20 +2341,21 @@ static int fetch_multiple(struct string_list *list, int max_children,
2341 * Fetching from the promisor remote should use the given filter-spec
2342 * or inherit the default filter-spec from the config.
2343 */
2342 -static inline void fetch_one_setup_partial(struct remote *remote)
2344 +static inline void fetch_one_setup_partial(struct remote *remote,
2345 + struct list_objects_filter_options *filter_options)
2346 {
2347 /*
2348 * Explicit --no-filter argument overrides everything, regardless
2349 * of any prior partial clones and fetches.
2350 */
2348 - if (filter_options.no_filter)
2351 + if (filter_options->no_filter)
2352 return;
2353
2354 /*
2355 * If no prior partial clone/fetch and the current fetch DID NOT
2356 * request a partial-fetch, do a normal fetch.
2357 */
2355 - if (!repo_has_promisor_remote(the_repository) && !filter_options.choice)
2358 + if (!repo_has_promisor_remote(the_repository) && !filter_options->choice)
2359 return;
2360
2361 /*
@@ -2361,8 +2364,8 @@ static inline void fetch_one_setup_partial(struct remote *remote)
2364 * filter-spec as the default for subsequent fetches to this
2365 * remote if there is currently no default filter-spec.
2366 */
2364 - if (filter_options.choice) {
2365 - partial_clone_register(remote->name, &filter_options);
2367 + if (filter_options->choice) {
2368 + partial_clone_register(remote->name, filter_options);
2369 return;
2370 }
2371
@@ -2371,14 +2374,15 @@ static inline void fetch_one_setup_partial(struct remote *remote)
2374 * explicitly given filter-spec or inherit the filter-spec from
2375 * the config.
2376 */
2374 - if (!filter_options.choice)
2375 - partial_clone_get_default_filter_spec(&filter_options, remote->name);
2377 + if (!filter_options->choice)
2378 + partial_clone_get_default_filter_spec(filter_options, remote->name);
2379 return;
2380 }
2381
2382 static int fetch_one(struct remote *remote, int argc, const char **argv,
2383 int prune_tags_ok, int use_stdin_refspecs,
2381 - const struct fetch_config *config)
2384 + const struct fetch_config *config,
2385 + struct list_objects_filter_options *filter_options)
2386 {
2387 struct refspec rs = REFSPEC_INIT_FETCH;
2388 int i;
@@ -2390,7 +2394,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv,
2394 die(_("no remote repository specified; please specify either a URL or a\n"
2395 "remote name from which new revisions should be fetched"));
2396
2393 - gtransport = prepare_transport(remote, 1);
2397 + gtransport = prepare_transport(remote, 1, filter_options);
2398
2399 if (prune < 0) {
2400 /* no command line request */
@@ -2445,7 +2449,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv,
2449 sigchain_push_common(unlock_pack_on_signal);
2450 atexit(unlock_pack_atexit);
2451 sigchain_push(SIGPIPE, SIG_IGN);
2448 - exit_code = do_fetch(gtransport, &rs, config);
2452 + exit_code = do_fetch(gtransport, &rs, config, filter_options);
2453 sigchain_pop(SIGPIPE);
2454 refspec_clear(&rs);
2455 transport_disconnect(gtransport);
@@ -2470,6 +2474,7 @@ int cmd_fetch(int argc,
2474 const char *submodule_prefix = "";
2475 const char *bundle_uri;
2476 struct string_list list = STRING_LIST_INIT_DUP;
2477 + struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT;
2478 struct remote *remote = NULL;
2479 int all = -1, multiple = 0;
2480 int result = 0;
@@ -2735,7 +2740,7 @@ int cmd_fetch(int argc,
2740 trace2_region_enter("fetch", "negotiate-only", the_repository);
2741 if (!remote)
2742 die(_("must supply remote when using --negotiate-only"));
2738 - gtransport = prepare_transport(remote, 1);
2743 + gtransport = prepare_transport(remote, 1, &filter_options);
2744 if (gtransport->smart_options) {
2745 gtransport->smart_options->acked_commits = &acked_commits;
2746 } else {
@@ -2757,12 +2762,12 @@ int cmd_fetch(int argc,
2762 } else if (remote) {
2763 if (filter_options.choice || repo_has_promisor_remote(the_repository)) {
2764 trace2_region_enter("fetch", "setup-partial", the_repository);
2760 - fetch_one_setup_partial(remote);
2765 + fetch_one_setup_partial(remote, &filter_options);
2766 trace2_region_leave("fetch", "setup-partial", the_repository);
2767 }
2768 trace2_region_enter("fetch", "fetch-one", the_repository);
2769 result = fetch_one(remote, argc, argv, prune_tags_ok, stdin_refspecs,
2765 - &config);
2770 + &config, &filter_options);
2771 trace2_region_leave("fetch", "fetch-one", the_repository);
2772 } else {
2773 int max_children = max_jobs;
@@ -2868,5 +2873,6 @@ int cmd_fetch(int argc,
2873
2874 cleanup:
2875 string_list_clear(&list, 0);
2876 + list_objects_filter_release(&filter_options);
2877 return result;
2878 }