@@ -346,27 +346,34 @@ static int update_local_ref(struct ref *ref,
346
346
}
347
347
348
348
/*
349
- * The ref_map records the tips of the refs we are fetching. If
349
+ * Take callback data, and return next object name in the buffer.
350
+ * When called after returning the name for the last object, return -1
351
+ * to signal EOF, otherwise return 0.
352
+ */
353
+ typedef int (* sha1_iterate_fn )(void * , unsigned char [20 ]);
354
+
355
+ /*
356
+ * If we feed all the commits we want to verify to this command
350
357
*
351
358
* $ git rev-list --verify-objects --stdin --not --all
352
359
*
353
- * (feeding all the refs in ref_map on its standard input) does not
354
- * error out, that means everything reachable from these updated refs
355
- * locally exists and is connected to some of our existing refs.
360
+ * and if it does not error out, that means everything reachable from
361
+ * these commits locally exists and is connected to some of our
362
+ * existing refs.
356
363
*
357
364
* Returns 0 if everything is connected, non-zero otherwise.
358
365
*/
359
- static int check_everything_connected (struct ref * ref_map , int quiet )
366
+ static int check_everything_connected (sha1_iterate_fn fn , int quiet , void * cb_data )
360
367
{
361
368
struct child_process rev_list ;
362
369
const char * argv [] = {"rev-list" , "--verify-objects" ,
363
370
"--stdin" , "--not" , "--all" , NULL , NULL };
364
371
char commit [41 ];
365
- struct ref * ref ;
372
+ unsigned char sha1 [ 20 ] ;
366
373
int err = 0 ;
367
374
368
- if (! ref_map )
369
- return 0 ;
375
+ if (fn ( cb_data , sha1 ) )
376
+ return err ;
370
377
371
378
if (quiet )
372
379
argv [5 ] = "--quiet" ;
@@ -383,26 +390,38 @@ static int check_everything_connected(struct ref *ref_map, int quiet)
383
390
sigchain_push (SIGPIPE , SIG_IGN );
384
391
385
392
commit [40 ] = '\n' ;
386
- for ( ref = ref_map ; ref ; ref = ref -> next ) {
387
- memcpy (commit , sha1_to_hex (ref -> old_sha1 ), 40 );
393
+ do {
394
+ memcpy (commit , sha1_to_hex (sha1 ), 40 );
388
395
if (write_in_full (rev_list .in , commit , 41 ) < 0 ) {
389
396
if (errno != EPIPE && errno != EINVAL )
390
397
error (_ ("failed write to rev-list: %s" ),
391
398
strerror (errno ));
392
399
err = -1 ;
393
400
break ;
394
401
}
395
- }
402
+ } while (!fn (cb_data , sha1 ));
403
+
396
404
if (close (rev_list .in )) {
397
405
error (_ ("failed to close rev-list's stdin: %s" ), strerror (errno ));
398
406
err = -1 ;
399
407
}
400
408
401
409
sigchain_pop (SIGPIPE );
402
-
403
410
return finish_command (& rev_list ) || err ;
404
411
}
405
412
413
+ static int iterate_ref_map (void * cb_data , unsigned char sha1 [20 ])
414
+ {
415
+ struct ref * * rm = cb_data ;
416
+ struct ref * ref = * rm ;
417
+
418
+ if (!ref )
419
+ return -1 ; /* end of the list */
420
+ * rm = ref -> next ;
421
+ hashcpy (sha1 , ref -> old_sha1 );
422
+ return 0 ;
423
+ }
424
+
406
425
static int store_updated_refs (const char * raw_url , const char * remote_name ,
407
426
struct ref * ref_map )
408
427
{
@@ -423,7 +442,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
423
442
else
424
443
url = xstrdup ("foreign" );
425
444
426
- if (check_everything_connected (ref_map , 0 ))
445
+ rm = ref_map ;
446
+ if (check_everything_connected (iterate_ref_map , 0 , & rm ))
427
447
return error (_ ("%s did not send all necessary objects\n" ), url );
428
448
429
449
for (rm = ref_map ; rm ; rm = rm -> next ) {
@@ -522,6 +542,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
522
542
*/
523
543
static int quickfetch (struct ref * ref_map )
524
544
{
545
+ struct ref * rm = ref_map ;
546
+
525
547
/*
526
548
* If we are deepening a shallow clone we already have these
527
549
* objects reachable. Running rev-list here will return with
@@ -531,7 +553,7 @@ static int quickfetch(struct ref *ref_map)
531
553
*/
532
554
if (depth )
533
555
return -1 ;
534
- return check_everything_connected (ref_map , 1 );
556
+ return check_everything_connected (iterate_ref_map , 1 , & rm );
535
557
}
536
558
537
559
static int fetch_refs (struct transport * transport , struct ref * ref_map )
0 commit comments