@@ -389,6 +389,20 @@ static struct string_list *fields_sent(void)
389
389
return & fields_list ;
390
390
}
391
391
392
+ static struct string_list * fields_checked (void )
393
+ {
394
+ static struct string_list fields_list = STRING_LIST_INIT_NODUP ;
395
+ static int initialized ;
396
+
397
+ if (!initialized ) {
398
+ fields_list .cmp = strcasecmp ;
399
+ fields_from_config (& fields_list , "promisor.checkFields" );
400
+ initialized = 1 ;
401
+ }
402
+
403
+ return & fields_list ;
404
+ }
405
+
392
406
/*
393
407
* Struct for promisor remotes involved in the "promisor-remote"
394
408
* protocol capability.
@@ -534,6 +548,61 @@ enum accept_promisor {
534
548
ACCEPT_ALL
535
549
};
536
550
551
+ static int match_field_against_config (const char * field , const char * value ,
552
+ struct promisor_info * config_info )
553
+ {
554
+ if (config_info -> filter && !strcasecmp (field , promisor_field_filter ))
555
+ return !strcmp (config_info -> filter , value );
556
+ else if (config_info -> token && !strcasecmp (field , promisor_field_token ))
557
+ return !strcmp (config_info -> token , value );
558
+
559
+ return 0 ;
560
+ }
561
+
562
+ static int all_fields_match (struct promisor_info * advertised ,
563
+ struct string_list * config_info ,
564
+ int in_list )
565
+ {
566
+ struct string_list * fields = fields_checked ();
567
+ struct string_list_item * item_checked ;
568
+
569
+ for_each_string_list_item (item_checked , fields ) {
570
+ int match = 0 ;
571
+ const char * field = item_checked -> string ;
572
+ const char * value = NULL ;
573
+ struct string_list_item * item ;
574
+
575
+ if (!strcasecmp (field , promisor_field_filter ))
576
+ value = advertised -> filter ;
577
+ else if (!strcasecmp (field , promisor_field_token ))
578
+ value = advertised -> token ;
579
+
580
+ if (!value )
581
+ return 0 ;
582
+
583
+ if (in_list ) {
584
+ for_each_string_list_item (item , config_info ) {
585
+ struct promisor_info * p = item -> util ;
586
+ if (match_field_against_config (field , value , p )) {
587
+ match = 1 ;
588
+ break ;
589
+ }
590
+ }
591
+ } else {
592
+ item = string_list_lookup (config_info , advertised -> name );
593
+ if (item ) {
594
+ struct promisor_info * p = item -> util ;
595
+ match = match_field_against_config (field , value , p );
596
+ }
597
+ }
598
+
599
+ if (!match )
600
+ return 0 ;
601
+ }
602
+
603
+ return 1 ;
604
+ }
605
+
537
606
static int should_accept_remote (enum accept_promisor accept ,
538
607
struct promisor_info * advertised ,
539
608
struct string_list * config_info )
@@ -544,7 +613,7 @@ static int should_accept_remote(enum accept_promisor accept,
544
613
const char * remote_url = advertised -> url ;
545
614
546
615
if (accept == ACCEPT_ALL )
547
- return 1 ;
616
+ return all_fields_match ( advertised , config_info , 1 ) ;
548
617
549
618
/* Get config info for that promisor remote */
550
619
item = string_list_lookup (config_info , remote_name );
@@ -556,7 +625,7 @@ static int should_accept_remote(enum accept_promisor accept,
556
625
p = item -> util ;
557
626
558
627
if (accept == ACCEPT_KNOWN_NAME )
559
- return 1 ;
628
+ return all_fields_match ( advertised , config_info , 0 ) ;
560
629
561
630
if (accept != ACCEPT_KNOWN_URL )
562
631
BUG ("Unhandled 'enum accept_promisor' value '%d'" , accept );
@@ -567,7 +636,7 @@ static int should_accept_remote(enum accept_promisor accept,
567
636
}
568
637
569
638
if (!strcmp (p -> url , remote_url ))
570
- return 1 ;
639
+ return all_fields_match ( advertised , config_info , 0 ) ;
571
640
572
641
warning (_ ("known remote named '%s' but with URL '%s' instead of '%s'" ),
573
642
remote_name , p -> url , remote_url );
@@ -605,6 +674,10 @@ static struct promisor_info *parse_one_advertised_remote(const char *remote_info
605
674
info -> name = url_percent_decode (p );
606
675
else if (skip_field_name_prefix (elem , promisor_field_url , & p ))
607
676
info -> url = url_percent_decode (p );
677
+ else if (skip_field_name_prefix (elem , promisor_field_filter , & p ))
678
+ info -> filter = url_percent_decode (p );
679
+ else if (skip_field_name_prefix (elem , promisor_field_token , & p ))
680
+ info -> token = url_percent_decode (p );
608
681
}
609
682
610
683
string_list_clear (& elem_list , 0 );
@@ -646,11 +719,6 @@ static void filter_promisor_remote(struct repository *repo,
646
719
if (accept == ACCEPT_NONE )
647
720
return ;
648
721
649
- if (accept != ACCEPT_ALL ) {
650
- promisor_config_info_list (repo , & config_info , NULL );
651
- string_list_sort (& config_info );
652
- }
653
-
654
722
/* Parse remote info received */
655
723
656
724
string_list_split (& remote_info , info , ";" , -1 );
@@ -663,6 +731,11 @@ static void filter_promisor_remote(struct repository *repo,
663
731
if (!advertised )
664
732
continue ;
665
733
734
+ if (!config_info .nr ) {
735
+ promisor_config_info_list (repo , & config_info , fields_checked ());
736
+ string_list_sort (& config_info );
737
+ }
738
+
666
739
if (should_accept_remote (accept , advertised , & config_info ))
667
740
strvec_push (accepted , advertised -> name );
668
741
0 commit comments