@@ -382,6 +382,20 @@ static struct string_list *fields_sent(void)
382
382
return & fields_list ;
383
383
}
384
384
385
+ static struct string_list * fields_checked (void )
386
+ {
387
+ static struct string_list fields_list = STRING_LIST_INIT_NODUP ;
388
+ static int initialized = 0 ;
389
+
390
+ if (!initialized ) {
391
+ fields_list .cmp = strcasecmp ;
392
+ fields_from_config (& fields_list , "promisor.checkFields" );
393
+ initialized = 1 ;
394
+ }
395
+
396
+ return & fields_list ;
397
+ }
398
+
385
399
/*
386
400
* Struct for promisor remotes involved in the "promisor-remote"
387
401
* protocol capability.
@@ -527,6 +541,61 @@ enum accept_promisor {
527
541
ACCEPT_ALL
528
542
};
529
543
544
+ static int match_field_against_config (const char * field , const char * value ,
545
+ struct promisor_info * config_info )
546
+ {
547
+ if (config_info -> filter && !strcasecmp (field , promisor_field_filter ))
548
+ return !strcmp (config_info -> filter , value );
549
+ else if (config_info -> token && !strcasecmp (field , promisor_field_token ))
550
+ return !strcmp (config_info -> token , value );
551
+
552
+ return 0 ;
553
+ }
554
+
555
+ static int all_fields_match (struct promisor_info * advertised ,
556
+ struct string_list * config_info ,
557
+ int in_list )
558
+ {
559
+ struct string_list * fields = fields_checked ();
560
+ struct string_list_item * item_checked ;
561
+
562
+ for_each_string_list_item (item_checked , fields ) {
563
+ int match = 0 ;
564
+ const char * field = item_checked -> string ;
565
+ const char * value = NULL ;
566
+ struct string_list_item * item ;
567
+
568
+ if (!strcasecmp (field , promisor_field_filter ))
569
+ value = advertised -> filter ;
570
+ else if (!strcasecmp (field , promisor_field_token ))
571
+ value = advertised -> token ;
572
+
573
+ if (!value )
574
+ return 0 ;
575
+
576
+ if (in_list ) {
577
+ for_each_string_list_item (item , config_info ) {
578
+ struct promisor_info * p = item -> util ;
579
+ if (match_field_against_config (field , value , p )) {
580
+ match = 1 ;
581
+ break ;
582
+ }
583
+ }
584
+ } else {
585
+ item = string_list_lookup (config_info , advertised -> name );
586
+ if (item ) {
587
+ struct promisor_info * p = item -> util ;
588
+ match = match_field_against_config (field , value , p );
589
+ }
590
+ }
591
+
592
+ if (!match )
593
+ return 0 ;
594
+ }
595
+
596
+ return 1 ;
597
+ }
598
+
530
599
static int should_accept_remote (enum accept_promisor accept ,
531
600
struct promisor_info * advertised ,
532
601
struct string_list * config_info )
@@ -537,7 +606,7 @@ static int should_accept_remote(enum accept_promisor accept,
537
606
const char * remote_url = advertised -> url ;
538
607
539
608
if (accept == ACCEPT_ALL )
540
- return 1 ;
609
+ return all_fields_match ( advertised , config_info , 1 ) ;
541
610
542
611
/* Get config info for that promisor remote */
543
612
item = string_list_lookup (config_info , remote_name );
@@ -549,7 +618,7 @@ static int should_accept_remote(enum accept_promisor accept,
549
618
p = item -> util ;
550
619
551
620
if (accept == ACCEPT_KNOWN_NAME )
552
- return 1 ;
621
+ return all_fields_match ( advertised , config_info , 0 ) ;
553
622
554
623
if (accept != ACCEPT_KNOWN_URL )
555
624
BUG ("Unhandled 'enum accept_promisor' value '%d'" , accept );
@@ -564,7 +633,7 @@ static int should_accept_remote(enum accept_promisor accept,
564
633
remote_name );
565
634
566
635
if (!strcmp (p -> url , remote_url ))
567
- return 1 ;
636
+ return all_fields_match ( advertised , config_info , 0 ) ;
568
637
569
638
warning (_ ("known remote named '%s' but with URL '%s' instead of '%s'" ),
570
639
remote_name , p -> url , remote_url );
@@ -596,6 +665,10 @@ static struct promisor_info *parse_one_advertised_remote(struct strbuf *remote_i
596
665
info -> name = value ;
597
666
else if (!strcmp (elem , "url" ))
598
667
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 ;
599
672
else
600
673
free (value );
601
674
}
@@ -638,11 +711,6 @@ static void filter_promisor_remote(struct repository *repo,
638
711
if (accept == ACCEPT_NONE )
639
712
return ;
640
713
641
- if (accept != ACCEPT_ALL ) {
642
- promisor_config_info_list (repo , & config_info , NULL );
643
- string_list_sort (& config_info );
644
- }
645
-
646
714
/* Parse remote info received */
647
715
648
716
remotes = strbuf_split_str (info , ';' , 0 );
@@ -657,6 +725,11 @@ static void filter_promisor_remote(struct repository *repo,
657
725
if (!advertised )
658
726
continue ;
659
727
728
+ if (!config_info .nr ) {
729
+ promisor_config_info_list (repo , & config_info , fields_checked ());
730
+ string_list_sort (& config_info );
731
+ }
732
+
660
733
if (should_accept_remote (accept , advertised , & config_info ))
661
734
strvec_push (accepted , advertised -> name );
662
735
0 commit comments