@@ -381,6 +381,20 @@ static struct string_list *fields_sent(void)
381381 return & fields_list ;
382382}
383383
384+ static struct string_list * fields_checked (void )
385+ {
386+ static struct string_list fields_list = STRING_LIST_INIT_NODUP ;
387+ static int initialized = 0 ;
388+
389+ if (!initialized ) {
390+ fields_list .cmp = strcasecmp ;
391+ fields_from_config (& fields_list , "promisor.checkFields" );
392+ initialized = 1 ;
393+ }
394+
395+ return & fields_list ;
396+ }
397+
384398/*
385399 * Linked list for promisor remotes involved in the "promisor-remote"
386400 * protocol capability.
@@ -537,6 +551,55 @@ enum accept_promisor {
537551 ACCEPT_ALL
538552};
539553
554+ static int match_field_against_config (const char * field , const char * value ,
555+ struct promisor_info * config_info )
556+ {
557+ if (config_info -> filter && !strcasecmp (field , promisor_field_filter ))
558+ return !strcmp (config_info -> filter , value );
559+ else if (config_info -> token && !strcasecmp (field , promisor_field_token ))
560+ return !strcmp (config_info -> token , value );
561+
562+ return 0 ;
563+ }
564+
565+ static int all_fields_match (struct promisor_info * advertised ,
566+ struct promisor_info * config_info ,
567+ int in_list )
568+ {
569+ struct string_list * fields = fields_checked ();
570+ struct string_list_item * item_checked ;
571+
572+ for_each_string_list_item (item_checked , fields ) {
573+ int match = 0 ;
574+ const char * field = item_checked -> string ;
575+ const char * value = NULL ;
576+
577+ if (!strcasecmp (field , promisor_field_filter ))
578+ value = advertised -> filter ;
579+ else if (!strcasecmp (field , promisor_field_token ))
580+ value = advertised -> token ;
581+
582+ if (!value )
583+ return 0 ;
584+
585+ if (in_list ) {
586+ for (struct promisor_info * p = config_info ; p ; p = p -> next ) {
587+ if (match_field_against_config (field , value , p )) {
588+ match = 1 ;
589+ break ;
590+ }
591+ }
592+ } else {
593+ match = match_field_against_config (field , value , config_info );
594+ }
595+
596+ if (!match )
597+ return 0 ;
598+ }
599+
600+ return 1 ;
601+ }
602+
540603static int should_accept_remote (enum accept_promisor accept ,
541604 struct promisor_info * advertised ,
542605 struct promisor_info * config_info )
@@ -546,7 +609,7 @@ static int should_accept_remote(enum accept_promisor accept,
546609 const char * remote_url = advertised -> url ;
547610
548611 if (accept == ACCEPT_ALL )
549- return 1 ;
612+ return all_fields_match ( advertised , config_info , 1 ) ;
550613
551614 p = remote_nick_find (config_info , remote_name );
552615
@@ -555,7 +618,7 @@ static int should_accept_remote(enum accept_promisor accept,
555618 return 0 ;
556619
557620 if (accept == ACCEPT_KNOWN_NAME )
558- return 1 ;
621+ return all_fields_match ( advertised , p , 0 ) ;
559622
560623 if (accept != ACCEPT_KNOWN_URL )
561624 BUG ("Unhandled 'enum accept_promisor' value '%d'" , accept );
@@ -570,7 +633,7 @@ static int should_accept_remote(enum accept_promisor accept,
570633 remote_name );
571634
572635 if (!strcmp (p -> url , remote_url ))
573- return 1 ;
636+ return all_fields_match ( advertised , p , 0 ) ;
574637
575638 warning (_ ("known remote named '%s' but with URL '%s' instead of '%s'" ),
576639 remote_name , p -> url , remote_url );
@@ -602,6 +665,10 @@ static struct promisor_info *parse_one_advertised_remote(struct strbuf *remote_i
602665 info -> name = value ;
603666 else if (!strcmp (elem , "url" ))
604667 info -> url = value ;
668+ else if (!strcasecmp (elem , promisor_field_filter ))
669+ info -> filter = value ;
670+ else if (!strcasecmp (elem , promisor_field_token ))
671+ info -> token = value ;
605672 else
606673 free (value );
607674 }
@@ -644,9 +711,6 @@ static void filter_promisor_remote(struct repository *repo,
644711 if (accept == ACCEPT_NONE )
645712 return ;
646713
647- if (accept != ACCEPT_ALL )
648- config_info = promisor_config_info_list (repo , NULL );
649-
650714 /* Parse remote info received */
651715
652716 remotes = strbuf_split_str (info , ';' , 0 );
@@ -661,6 +725,9 @@ static void filter_promisor_remote(struct repository *repo,
661725 if (!advertised )
662726 continue ;
663727
728+ if (!config_info )
729+ config_info = promisor_config_info_list (repo , fields_checked ());
730+
664731 if (should_accept_remote (accept , advertised , config_info ))
665732 strvec_push (accepted , advertised -> name );
666733
0 commit comments