88#include "tag.h"
99#include "string-list.h"
1010
11+ enum map_direction { FROM_SRC , FROM_DST };
12+
1113static struct refspec s_tag_refspec = {
1214 0 ,
1315 1 ,
@@ -978,16 +980,20 @@ static void tail_link_ref(struct ref *ref, struct ref ***tail)
978980 * tail = & ref -> next ;
979981}
980982
983+ static struct ref * alloc_delete_ref (void )
984+ {
985+ struct ref * ref = alloc_ref ("(delete)" );
986+ hashclr (ref -> new_sha1 );
987+ return ref ;
988+ }
989+
981990static struct ref * try_explicit_object_name (const char * name )
982991{
983992 unsigned char sha1 [20 ];
984993 struct ref * ref ;
985994
986- if (!* name ) {
987- ref = alloc_ref ("(delete)" );
988- hashclr (ref -> new_sha1 );
989- return ref ;
990- }
995+ if (!* name )
996+ return alloc_delete_ref ();
991997 if (get_sha1 (name , sha1 ))
992998 return NULL ;
993999 ref = alloc_ref (name );
@@ -1110,10 +1116,11 @@ static int match_explicit_refs(struct ref *src, struct ref *dst,
11101116 return errs ;
11111117}
11121118
1113- static const struct refspec * check_pattern_match (const struct refspec * rs ,
1114- int rs_nr ,
1115- const struct ref * src )
1119+ static char * get_ref_match (const struct refspec * rs , int rs_nr , const struct ref * ref ,
1120+ int send_mirror , int direction , const struct refspec * * ret_pat )
11161121{
1122+ const struct refspec * pat ;
1123+ char * name ;
11171124 int i ;
11181125 int matching_refs = -1 ;
11191126 for (i = 0 ; i < rs_nr ; i ++ ) {
@@ -1123,14 +1130,36 @@ static const struct refspec *check_pattern_match(const struct refspec *rs,
11231130 continue ;
11241131 }
11251132
1126- if (rs [i ].pattern && match_name_with_pattern (rs [i ].src , src -> name ,
1127- NULL , NULL ))
1128- return rs + i ;
1133+ if (rs [i ].pattern ) {
1134+ const char * dst_side = rs [i ].dst ? rs [i ].dst : rs [i ].src ;
1135+ int match ;
1136+ if (direction == FROM_SRC )
1137+ match = match_name_with_pattern (rs [i ].src , ref -> name , dst_side , & name );
1138+ else
1139+ match = match_name_with_pattern (dst_side , ref -> name , rs [i ].src , & name );
1140+ if (match ) {
1141+ matching_refs = i ;
1142+ break ;
1143+ }
1144+ }
11291145 }
1130- if (matching_refs != -1 )
1131- return rs + matching_refs ;
1132- else
1146+ if (matching_refs == -1 )
11331147 return NULL ;
1148+
1149+ pat = rs + matching_refs ;
1150+ if (pat -> matching ) {
1151+ /*
1152+ * "matching refs"; traditionally we pushed everything
1153+ * including refs outside refs/heads/ hierarchy, but
1154+ * that does not make much sense these days.
1155+ */
1156+ if (!send_mirror && prefixcmp (ref -> name , "refs/heads/" ))
1157+ return NULL ;
1158+ name = xstrdup (ref -> name );
1159+ }
1160+ if (ret_pat )
1161+ * ret_pat = pat ;
1162+ return name ;
11341163}
11351164
11361165static struct ref * * tail_ref (struct ref * * head )
@@ -1155,9 +1184,10 @@ int match_push_refs(struct ref *src, struct ref **dst,
11551184 struct refspec * rs ;
11561185 int send_all = flags & MATCH_REFS_ALL ;
11571186 int send_mirror = flags & MATCH_REFS_MIRROR ;
1187+ int send_prune = flags & MATCH_REFS_PRUNE ;
11581188 int errs ;
11591189 static const char * default_refspec [] = { ":" , NULL };
1160- struct ref * * dst_tail = tail_ref (dst );
1190+ struct ref * ref , * * dst_tail = tail_ref (dst );
11611191
11621192 if (!nr_refspec ) {
11631193 nr_refspec = 1 ;
@@ -1167,39 +1197,23 @@ int match_push_refs(struct ref *src, struct ref **dst,
11671197 errs = match_explicit_refs (src , * dst , & dst_tail , rs , nr_refspec );
11681198
11691199 /* pick the remainder */
1170- for ( ; src ; src = src -> next ) {
1200+ for (ref = src ; ref ; ref = ref -> next ) {
11711201 struct ref * dst_peer ;
11721202 const struct refspec * pat = NULL ;
11731203 char * dst_name ;
1174- if (src -> peer_ref )
1175- continue ;
11761204
1177- pat = check_pattern_match (rs , nr_refspec , src );
1178- if (!pat )
1205+ if (ref -> peer_ref )
11791206 continue ;
11801207
1181- if (pat -> matching ) {
1182- /*
1183- * "matching refs"; traditionally we pushed everything
1184- * including refs outside refs/heads/ hierarchy, but
1185- * that does not make much sense these days.
1186- */
1187- if (!send_mirror && prefixcmp (src -> name , "refs/heads/" ))
1188- continue ;
1189- dst_name = xstrdup (src -> name );
1208+ dst_name = get_ref_match (rs , nr_refspec , ref , send_mirror , FROM_SRC , & pat );
1209+ if (!dst_name )
1210+ continue ;
11901211
1191- } else {
1192- const char * dst_side = pat -> dst ? pat -> dst : pat -> src ;
1193- if (!match_name_with_pattern (pat -> src , src -> name ,
1194- dst_side , & dst_name ))
1195- die ("Didn't think it matches any more" );
1196- }
11971212 dst_peer = find_ref_by_name (* dst , dst_name );
11981213 if (dst_peer ) {
11991214 if (dst_peer -> peer_ref )
12001215 /* We're already sending something to this ref. */
12011216 goto free_name ;
1202-
12031217 } else {
12041218 if (pat -> matching && !(send_all || send_mirror ))
12051219 /*
@@ -1211,13 +1225,30 @@ int match_push_refs(struct ref *src, struct ref **dst,
12111225
12121226 /* Create a new one and link it */
12131227 dst_peer = make_linked_ref (dst_name , & dst_tail );
1214- hashcpy (dst_peer -> new_sha1 , src -> new_sha1 );
1228+ hashcpy (dst_peer -> new_sha1 , ref -> new_sha1 );
12151229 }
1216- dst_peer -> peer_ref = copy_ref (src );
1230+ dst_peer -> peer_ref = copy_ref (ref );
12171231 dst_peer -> force = pat -> force ;
12181232 free_name :
12191233 free (dst_name );
12201234 }
1235+ if (send_prune ) {
1236+ /* check for missing refs on the remote */
1237+ for (ref = * dst ; ref ; ref = ref -> next ) {
1238+ char * src_name ;
1239+
1240+ if (ref -> peer_ref )
1241+ /* We're already sending something to this ref. */
1242+ continue ;
1243+
1244+ src_name = get_ref_match (rs , nr_refspec , ref , send_mirror , FROM_DST , NULL );
1245+ if (src_name ) {
1246+ if (!find_ref_by_name (src , src_name ))
1247+ ref -> peer_ref = alloc_delete_ref ();
1248+ free (src_name );
1249+ }
1250+ }
1251+ }
12211252 if (errs )
12221253 return -1 ;
12231254 return 0 ;
0 commit comments