@@ -504,57 +504,98 @@ static int will_fetch(struct ref **head, const unsigned char *sha1)
504504 return 0 ;
505505}
506506
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+
507531static void find_non_local_tags (struct transport * transport ,
508532 struct ref * * head ,
509533 struct ref * * * tail )
510534{
511535 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 };
518538 const struct ref * ref ;
539+ struct string_list_item * item = NULL ;
519540
520541 for_each_ref (add_existing , & existing_refs );
521542 for (ref = transport_get_remote_refs (transport ); ref ; ref = ref -> next ) {
522543 if (prefixcmp (ref -> name , "refs/tags" ))
523544 continue ;
524545
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 ;
539560 }
540561
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 ;
546571
547- rm = alloc_ref (ref_name );
548- rm -> peer_ref = alloc_ref (ref_name );
549- hashcpy (rm -> old_sha1 , ref_sha1 );
572+ item = NULL ;
550573
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 ;
555581 }
556582 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 );
558599}
559600
560601static void check_not_current_branch (struct ref * ref_map )
0 commit comments