@@ -1302,6 +1302,14 @@ static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***ds
1302
1302
free (sent_tips .tip );
1303
1303
}
1304
1304
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
+
1305
1313
/*
1306
1314
* Given the set of refs the local repository has, the set of refs the
1307
1315
* remote repository has, and the refspec used for push, determine
@@ -1320,6 +1328,7 @@ int match_push_refs(struct ref *src, struct ref **dst,
1320
1328
int errs ;
1321
1329
static const char * default_refspec [] = { ":" , NULL };
1322
1330
struct ref * ref , * * dst_tail = tail_ref (dst );
1331
+ struct string_list dst_ref_index = STRING_LIST_INIT_NODUP ;
1323
1332
1324
1333
if (!nr_refspec ) {
1325
1334
nr_refspec = 1 ;
@@ -1330,6 +1339,7 @@ int match_push_refs(struct ref *src, struct ref **dst,
1330
1339
1331
1340
/* pick the remainder */
1332
1341
for (ref = src ; ref ; ref = ref -> next ) {
1342
+ struct string_list_item * dst_item ;
1333
1343
struct ref * dst_peer ;
1334
1344
const struct refspec * pat = NULL ;
1335
1345
char * dst_name ;
@@ -1338,7 +1348,11 @@ int match_push_refs(struct ref *src, struct ref **dst,
1338
1348
if (!dst_name )
1339
1349
continue ;
1340
1350
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 ;
1342
1356
if (dst_peer ) {
1343
1357
if (dst_peer -> peer_ref )
1344
1358
/* We're already sending something to this ref. */
@@ -1355,17 +1369,22 @@ int match_push_refs(struct ref *src, struct ref **dst,
1355
1369
/* Create a new one and link it */
1356
1370
dst_peer = make_linked_ref (dst_name , & dst_tail );
1357
1371
hashcpy (dst_peer -> new_sha1 , ref -> new_sha1 );
1372
+ string_list_insert (& dst_ref_index ,
1373
+ dst_peer -> name )-> util = dst_peer ;
1358
1374
}
1359
1375
dst_peer -> peer_ref = copy_ref (ref );
1360
1376
dst_peer -> force = pat -> force ;
1361
1377
free_name :
1362
1378
free (dst_name );
1363
1379
}
1364
1380
1381
+ string_list_clear (& dst_ref_index , 0 );
1382
+
1365
1383
if (flags & MATCH_REFS_FOLLOW_TAGS )
1366
1384
add_missing_tags (src , dst , & dst_tail );
1367
1385
1368
1386
if (send_prune ) {
1387
+ struct string_list src_ref_index = STRING_LIST_INIT_NODUP ;
1369
1388
/* check for missing refs on the remote */
1370
1389
for (ref = * dst ; ref ; ref = ref -> next ) {
1371
1390
char * src_name ;
@@ -1376,11 +1395,15 @@ int match_push_refs(struct ref *src, struct ref **dst,
1376
1395
1377
1396
src_name = get_ref_match (rs , nr_refspec , ref , send_mirror , FROM_DST , NULL );
1378
1397
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 ))
1380
1402
ref -> peer_ref = alloc_delete_ref ();
1381
1403
free (src_name );
1382
1404
}
1383
1405
}
1406
+ string_list_clear (& src_ref_index , 0 );
1384
1407
}
1385
1408
if (errs )
1386
1409
return -1 ;
0 commit comments