@@ -271,6 +271,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
271271 int new_refs ;
272272 int ret = 0 ;
273273 int ask_for_status_report = 0 ;
274+ int allow_deleting_refs = 0 ;
274275 int expect_status_report = 0 ;
275276
276277 /* No funny business with the matcher */
@@ -280,6 +281,8 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
280281 /* Does the other end support the reporting? */
281282 if (server_supports ("report-status" ))
282283 ask_for_status_report = 1 ;
284+ if (server_supports ("delete-refs" ))
285+ allow_deleting_refs = 1 ;
283286
284287 /* match them up */
285288 if (!remote_tail )
@@ -299,9 +302,19 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
299302 new_refs = 0 ;
300303 for (ref = remote_refs ; ref ; ref = ref -> next ) {
301304 char old_hex [60 ], * new_hex ;
305+ int delete_ref ;
306+
302307 if (!ref -> peer_ref )
303308 continue ;
304- if (!hashcmp (ref -> old_sha1 , ref -> peer_ref -> new_sha1 )) {
309+
310+ delete_ref = is_null_sha1 (ref -> peer_ref -> new_sha1 );
311+ if (delete_ref && !allow_deleting_refs ) {
312+ error ("remote does not support deleting refs" );
313+ ret = -2 ;
314+ continue ;
315+ }
316+ if (!delete_ref &&
317+ !hashcmp (ref -> old_sha1 , ref -> peer_ref -> new_sha1 )) {
305318 if (verbose )
306319 fprintf (stderr , "'%s': up-to-date\n" , ref -> name );
307320 continue ;
@@ -321,9 +334,13 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
321334 *
322335 * (3) if both new and old are commit-ish, and new is a
323336 * descendant of old, it is OK.
337+ *
338+ * (4) regardless of all of the above, removing :B is
339+ * always allowed.
324340 */
325341
326342 if (!force_update &&
343+ !delete_ref &&
327344 !is_zero_sha1 (ref -> old_sha1 ) &&
328345 !ref -> force ) {
329346 if (!has_sha1_file (ref -> old_sha1 ) ||
@@ -347,12 +364,8 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
347364 }
348365 }
349366 hashcpy (ref -> new_sha1 , ref -> peer_ref -> new_sha1 );
350- if (is_zero_sha1 (ref -> new_sha1 )) {
351- error ("cannot happen anymore" );
352- ret = -3 ;
353- continue ;
354- }
355- new_refs ++ ;
367+ if (!delete_ref )
368+ new_refs ++ ;
356369 strcpy (old_hex , sha1_to_hex (ref -> old_sha1 ));
357370 new_hex = sha1_to_hex (ref -> new_sha1 );
358371
@@ -366,10 +379,16 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
366379 else
367380 packet_write (out , "%s %s %s" ,
368381 old_hex , new_hex , ref -> name );
369- fprintf (stderr , "updating '%s'" , ref -> name );
370- if (strcmp (ref -> name , ref -> peer_ref -> name ))
371- fprintf (stderr , " using '%s'" , ref -> peer_ref -> name );
372- fprintf (stderr , "\n from %s\n to %s\n" , old_hex , new_hex );
382+ if (delete_ref )
383+ fprintf (stderr , "deleting '%s'\n" , ref -> name );
384+ else {
385+ fprintf (stderr , "updating '%s'" , ref -> name );
386+ if (strcmp (ref -> name , ref -> peer_ref -> name ))
387+ fprintf (stderr , " using '%s'" ,
388+ ref -> peer_ref -> name );
389+ fprintf (stderr , "\n from %s\n to %s\n" ,
390+ old_hex , new_hex );
391+ }
373392 }
374393
375394 packet_flush (out );
0 commit comments