@@ -391,7 +391,18 @@ static void *get_data_from_pack(struct object_entry *obj)
391
391
return data ;
392
392
}
393
393
394
- static int find_delta (const union delta_base * base )
394
+ static int compare_delta_bases (const union delta_base * base1 ,
395
+ const union delta_base * base2 ,
396
+ enum object_type type1 ,
397
+ enum object_type type2 )
398
+ {
399
+ int cmp = type1 - type2 ;
400
+ if (cmp )
401
+ return cmp ;
402
+ return memcmp (base1 , base2 , UNION_BASE_SZ );
403
+ }
404
+
405
+ static int find_delta (const union delta_base * base , enum object_type type )
395
406
{
396
407
int first = 0 , last = nr_deltas ;
397
408
@@ -400,7 +411,8 @@ static int find_delta(const union delta_base *base)
400
411
struct delta_entry * delta = & deltas [next ];
401
412
int cmp ;
402
413
403
- cmp = memcmp (base , & delta -> base , UNION_BASE_SZ );
414
+ cmp = compare_delta_bases (base , & delta -> base ,
415
+ type , objects [delta -> obj_no ].type );
404
416
if (!cmp )
405
417
return next ;
406
418
if (cmp < 0 ) {
@@ -413,9 +425,10 @@ static int find_delta(const union delta_base *base)
413
425
}
414
426
415
427
static void find_delta_children (const union delta_base * base ,
416
- int * first_index , int * last_index )
428
+ int * first_index , int * last_index ,
429
+ enum object_type type )
417
430
{
418
- int first = find_delta (base );
431
+ int first = find_delta (base , type );
419
432
int last = first ;
420
433
int end = nr_deltas - 1 ;
421
434
@@ -543,11 +556,13 @@ static void find_unresolved_deltas(struct base_data *base,
543
556
union delta_base base_spec ;
544
557
545
558
hashcpy (base_spec .sha1 , base -> obj -> idx .sha1 );
546
- find_delta_children (& base_spec , & ref_first , & ref_last );
559
+ find_delta_children (& base_spec ,
560
+ & ref_first , & ref_last , OBJ_REF_DELTA );
547
561
548
562
memset (& base_spec , 0 , sizeof (base_spec ));
549
563
base_spec .offset = base -> obj -> idx .offset ;
550
- find_delta_children (& base_spec , & ofs_first , & ofs_last );
564
+ find_delta_children (& base_spec ,
565
+ & ofs_first , & ofs_last , OBJ_OFS_DELTA );
551
566
}
552
567
553
568
if (ref_last == -1 && ofs_last == -1 ) {
@@ -559,24 +574,24 @@ static void find_unresolved_deltas(struct base_data *base,
559
574
560
575
for (i = ref_first ; i <= ref_last ; i ++ ) {
561
576
struct object_entry * child = objects + deltas [i ].obj_no ;
562
- if ( child -> real_type == OBJ_REF_DELTA ) {
563
- struct base_data result ;
564
- resolve_delta (child , base , & result );
565
- if ( i == ref_last && ofs_last == -1 )
566
- free_base_data ( base );
567
- find_unresolved_deltas ( & result , base );
568
- }
577
+ struct base_data result ;
578
+
579
+ assert (child -> real_type == OBJ_REF_DELTA );
580
+ resolve_delta ( child , base , & result );
581
+ if ( i == ref_last && ofs_last == -1 )
582
+ free_base_data ( base );
583
+ find_unresolved_deltas ( & result , base );
569
584
}
570
585
571
586
for (i = ofs_first ; i <= ofs_last ; i ++ ) {
572
587
struct object_entry * child = objects + deltas [i ].obj_no ;
573
- if ( child -> real_type == OBJ_OFS_DELTA ) {
574
- struct base_data result ;
575
- resolve_delta (child , base , & result );
576
- if ( i == ofs_last )
577
- free_base_data ( base );
578
- find_unresolved_deltas ( & result , base );
579
- }
588
+ struct base_data result ;
589
+
590
+ assert (child -> real_type == OBJ_OFS_DELTA );
591
+ resolve_delta ( child , base , & result );
592
+ if ( i == ofs_last )
593
+ free_base_data ( base );
594
+ find_unresolved_deltas ( & result , base );
580
595
}
581
596
582
597
unlink_base_data (base );
@@ -586,7 +601,11 @@ static int compare_delta_entry(const void *a, const void *b)
586
601
{
587
602
const struct delta_entry * delta_a = a ;
588
603
const struct delta_entry * delta_b = b ;
589
- return memcmp (& delta_a -> base , & delta_b -> base , UNION_BASE_SZ );
604
+
605
+ /* group by type (ref vs ofs) and then by value (sha-1 or offset) */
606
+ return compare_delta_bases (& delta_a -> base , & delta_b -> base ,
607
+ objects [delta_a -> obj_no ].type ,
608
+ objects [delta_b -> obj_no ].type );
590
609
}
591
610
592
611
/* Parse all objects and return the pack content SHA1 hash */
0 commit comments