@@ -1302,6 +1302,14 @@ static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***ds
13021302 free (sent_tips .tip );
13031303}
13041304
1305+ static void prepare_ref_index (struct string_list * ref_index , struct ref * ref )
1306+ {
1307+ for ( ; ref ; ref = ref -> next )
1308+ string_list_append_nodup (ref_index , ref -> name )-> util = ref ;
1309+
1310+ sort_string_list (ref_index );
1311+ }
1312+
13051313/*
13061314 * Given the set of refs the local repository has, the set of refs the
13071315 * remote repository has, and the refspec used for push, determine
@@ -1320,6 +1328,7 @@ int match_push_refs(struct ref *src, struct ref **dst,
13201328 int errs ;
13211329 static const char * default_refspec [] = { ":" , NULL };
13221330 struct ref * ref , * * dst_tail = tail_ref (dst );
1331+ struct string_list dst_ref_index = STRING_LIST_INIT_NODUP ;
13231332
13241333 if (!nr_refspec ) {
13251334 nr_refspec = 1 ;
@@ -1330,6 +1339,7 @@ int match_push_refs(struct ref *src, struct ref **dst,
13301339
13311340 /* pick the remainder */
13321341 for (ref = src ; ref ; ref = ref -> next ) {
1342+ struct string_list_item * dst_item ;
13331343 struct ref * dst_peer ;
13341344 const struct refspec * pat = NULL ;
13351345 char * dst_name ;
@@ -1338,7 +1348,11 @@ int match_push_refs(struct ref *src, struct ref **dst,
13381348 if (!dst_name )
13391349 continue ;
13401350
1341- dst_peer = find_ref_by_name (* dst , dst_name );
1351+ if (!dst_ref_index .nr )
1352+ prepare_ref_index (& dst_ref_index , * dst );
1353+
1354+ dst_item = string_list_lookup (& dst_ref_index , dst_name );
1355+ dst_peer = dst_item ? dst_item -> util : NULL ;
13421356 if (dst_peer ) {
13431357 if (dst_peer -> peer_ref )
13441358 /* We're already sending something to this ref. */
@@ -1355,17 +1369,22 @@ int match_push_refs(struct ref *src, struct ref **dst,
13551369 /* Create a new one and link it */
13561370 dst_peer = make_linked_ref (dst_name , & dst_tail );
13571371 hashcpy (dst_peer -> new_sha1 , ref -> new_sha1 );
1372+ string_list_insert (& dst_ref_index ,
1373+ dst_peer -> name )-> util = dst_peer ;
13581374 }
13591375 dst_peer -> peer_ref = copy_ref (ref );
13601376 dst_peer -> force = pat -> force ;
13611377 free_name :
13621378 free (dst_name );
13631379 }
13641380
1381+ string_list_clear (& dst_ref_index , 0 );
1382+
13651383 if (flags & MATCH_REFS_FOLLOW_TAGS )
13661384 add_missing_tags (src , dst , & dst_tail );
13671385
13681386 if (send_prune ) {
1387+ struct string_list src_ref_index = STRING_LIST_INIT_NODUP ;
13691388 /* check for missing refs on the remote */
13701389 for (ref = * dst ; ref ; ref = ref -> next ) {
13711390 char * src_name ;
@@ -1376,11 +1395,15 @@ int match_push_refs(struct ref *src, struct ref **dst,
13761395
13771396 src_name = get_ref_match (rs , nr_refspec , ref , send_mirror , FROM_DST , NULL );
13781397 if (src_name ) {
1379- if (!find_ref_by_name (src , src_name ))
1398+ if (!src_ref_index .nr )
1399+ prepare_ref_index (& src_ref_index , src );
1400+ if (!string_list_has_string (& src_ref_index ,
1401+ src_name ))
13801402 ref -> peer_ref = alloc_delete_ref ();
13811403 free (src_name );
13821404 }
13831405 }
1406+ string_list_clear (& src_ref_index , 0 );
13841407 }
13851408 if (errs )
13861409 return -1 ;
0 commit comments