@@ -504,57 +504,98 @@ static int will_fetch(struct ref **head, const unsigned char *sha1)
504
504
return 0 ;
505
505
}
506
506
507
+ struct tag_data {
508
+ struct ref * * head ;
509
+ struct ref * * * tail ;
510
+ };
511
+
512
+ static int add_to_tail (struct string_list_item * item , void * cb_data )
513
+ {
514
+ struct tag_data * data = (struct tag_data * )cb_data ;
515
+ struct ref * rm = NULL ;
516
+
517
+ /* We have already decided to ignore this item */
518
+ if (!item -> util )
519
+ return 0 ;
520
+
521
+ rm = alloc_ref (item -> string );
522
+ rm -> peer_ref = alloc_ref (item -> string );
523
+ hashcpy (rm -> old_sha1 , item -> util );
524
+
525
+ * * data -> tail = rm ;
526
+ * data -> tail = & rm -> next ;
527
+
528
+ return 0 ;
529
+ }
530
+
507
531
static void find_non_local_tags (struct transport * transport ,
508
532
struct ref * * head ,
509
533
struct ref * * * tail )
510
534
{
511
535
struct string_list existing_refs = { NULL , 0 , 0 , 0 };
512
- struct string_list new_refs = { NULL , 0 , 0 , 1 };
513
- char * ref_name ;
514
- int ref_name_len ;
515
- const unsigned char * ref_sha1 ;
516
- const struct ref * tag_ref ;
517
- struct ref * rm = NULL ;
536
+ struct string_list remote_refs = { NULL , 0 , 0 , 0 };
537
+ struct tag_data data = {head , tail };
518
538
const struct ref * ref ;
539
+ struct string_list_item * item = NULL ;
519
540
520
541
for_each_ref (add_existing , & existing_refs );
521
542
for (ref = transport_get_remote_refs (transport ); ref ; ref = ref -> next ) {
522
543
if (prefixcmp (ref -> name , "refs/tags" ))
523
544
continue ;
524
545
525
- ref_name = xstrdup ( ref -> name );
526
- ref_name_len = strlen ( ref_name );
527
- ref_sha1 = ref -> old_sha1 ;
528
-
529
- if (! strcmp ( ref_name + ref_name_len - 3 , "^{}" )) {
530
- ref_name [ ref_name_len - 3 ] = 0 ;
531
- tag_ref = transport_get_remote_refs ( transport );
532
- while ( tag_ref ) {
533
- if (! strcmp ( tag_ref -> name , ref_name )) {
534
- ref_sha1 = tag_ref -> old_sha1 ;
535
- break ;
536
- }
537
- tag_ref = tag_ref -> next ;
538
- }
546
+ /*
547
+ * The peeled ref always follows the matching base
548
+ * ref, so if we see a peeled ref that we don't want
549
+ * to fetch then we can mark the ref entry in the list
550
+ * as one to ignore by setting util to NULL.
551
+ */
552
+ if (! strcmp ( ref -> name + strlen ( ref -> name ) - 3 , "^{}" )) {
553
+ if ( item && ! has_sha1_file ( ref -> old_sha1 ) &&
554
+ ! will_fetch ( head , ref -> old_sha1 ) &&
555
+ ! has_sha1_file ( item -> util ) &&
556
+ ! will_fetch ( head , item -> util ))
557
+ item -> util = NULL ;
558
+ item = NULL ;
559
+ continue ;
539
560
}
540
561
541
- if (!string_list_has_string (& existing_refs , ref_name ) &&
542
- !string_list_has_string (& new_refs , ref_name ) &&
543
- (has_sha1_file (ref -> old_sha1 ) ||
544
- will_fetch (head , ref -> old_sha1 ))) {
545
- string_list_insert (ref_name , & new_refs );
562
+ /*
563
+ * If item is non-NULL here, then we previously saw a
564
+ * ref not followed by a peeled reference, so we need
565
+ * to check if it is a lightweight tag that we want to
566
+ * fetch.
567
+ */
568
+ if (item && !has_sha1_file (item -> util ) &&
569
+ !will_fetch (head , item -> util ))
570
+ item -> util = NULL ;
546
571
547
- rm = alloc_ref (ref_name );
548
- rm -> peer_ref = alloc_ref (ref_name );
549
- hashcpy (rm -> old_sha1 , ref_sha1 );
572
+ item = NULL ;
550
573
551
- * * tail = rm ;
552
- * tail = & rm -> next ;
553
- }
554
- free (ref_name );
574
+ /* skip duplicates and refs that we already have */
575
+ if (string_list_has_string (& remote_refs , ref -> name ) ||
576
+ string_list_has_string (& existing_refs , ref -> name ))
577
+ continue ;
578
+
579
+ item = string_list_insert (ref -> name , & remote_refs );
580
+ item -> util = (void * )ref -> old_sha1 ;
555
581
}
556
582
string_list_clear (& existing_refs , 0 );
557
- string_list_clear (& new_refs , 0 );
583
+
584
+ /*
585
+ * We may have a final lightweight tag that needs to be
586
+ * checked to see if it needs fetching.
587
+ */
588
+ if (item && !has_sha1_file (item -> util ) &&
589
+ !will_fetch (head , item -> util ))
590
+ item -> util = NULL ;
591
+
592
+ /*
593
+ * For all the tags in the remote_refs string list, call
594
+ * add_to_tail to add them to the list of refs to be fetched
595
+ */
596
+ for_each_string_list (add_to_tail , & remote_refs , & data );
597
+
598
+ string_list_clear (& remote_refs , 0 );
558
599
}
559
600
560
601
static void check_not_current_branch (struct ref * ref_map )
0 commit comments