promisor-remote: keep accepted promisor_info structs alive

In filter_promisor_remote(), the instances of `struct promisor_info` for accepted remotes are dismantled into separate parallel data structures (the 'accepted' strvec for server names, and 'accepted_filters' for filter strings) and then immediately freed. Instead, let's keep these instances on an 'accepted_remotes' list. This way the post-loop phase can iterate a single list to build the protocol reply, apply advertised filters, and mark remotes as accepted, rather than iterating three separate structures. This refactoring also prepares for a future commit that will add a 'local_name' member to 'struct promisor_info'. Since struct instances stay alive, downstream code will be able to simply read both names from them rather than needing yet another parallel strvec. Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Christian Couder committed Apr 7, 2026 at 13:52 UTC e0f80d8876960442dd2645215c4fe5e1b1d80fc3
1 file changed +17 -25
promisor-remote.c
+17 -25
@@ -890,10 +890,10 @@ static void filter_promisor_remote(struct repository *repo,
890 {
891 struct string_list config_info = STRING_LIST_INIT_NODUP;
892 struct string_list remote_info = STRING_LIST_INIT_DUP;
893 + struct string_list accepted_remotes = STRING_LIST_INIT_NODUP;
894 struct store_info *store_info = NULL;
895 struct string_list_item *item;
896 bool reload_config = false;
896 - struct string_list accepted_filters = STRING_LIST_INIT_DUP;
897 enum accept_promisor accept = accept_from_server(repo);
898
899 if (accept == ACCEPT_NONE)
@@ -922,17 +922,10 @@ static void filter_promisor_remote(struct repository *repo,
922 if (promisor_store_advertised_fields(advertised, store_info))
923 reload_config = true;
924
925 - strvec_push(accepted, advertised->name);
926 -
927 - /* Capture advertised filters for accepted remotes */
928 - if (advertised->filter) {
929 - struct string_list_item *i;
930 - i = string_list_append(&accepted_filters, advertised->name);
931 - i->util = xstrdup(advertised->filter);
932 - }
925 + string_list_append(&accepted_remotes, advertised->name)->util = advertised;
926 + } else {
927 + promisor_info_free(advertised);
928 }
934 -
935 - promisor_info_free(advertised);
929 }
930
931 promisor_info_list_clear(&config_info);
@@ -942,24 +935,23 @@ static void filter_promisor_remote(struct repository *repo,
935 if (reload_config)
936 repo_promisor_remote_reinit(repo);
937
945 - /* Apply accepted remote filters to the stable repo state */
946 - for_each_string_list_item(item, &accepted_filters) {
947 - struct promisor_remote *r = repo_promisor_remote_find(repo, item->string);
948 - if (r) {
949 - free(r->advertised_filter);
950 - r->advertised_filter = item->util;
951 - item->util = NULL;
952 - }
953 - }
938 + /* Apply accepted remotes to the stable repo state */
939 + for_each_string_list_item(item, &accepted_remotes) {
940 + struct promisor_info *info = item->util;
941 + struct promisor_remote *r = repo_promisor_remote_find(repo, info->name);
942
955 - string_list_clear(&accepted_filters, 1);
943 + strvec_push(accepted, info->name);
944
957 - /* Mark the remotes as accepted in the repository state */
958 - for (size_t i = 0; i < accepted->nr; i++) {
959 - struct promisor_remote *r = repo_promisor_remote_find(repo, accepted->v[i]);
960 - if (r)
945 + if (r) {
946 r->accepted = 1;
947 + if (info->filter) {
948 + free(r->advertised_filter);
949 + r->advertised_filter = xstrdup(info->filter);
950 + }
951 + }
952 }
953 +
954 + promisor_info_list_clear(&accepted_remotes);
955 }
956
957 void promisor_remote_reply(const char *info, char **accepted_out)