@@ -153,7 +153,9 @@ static void unique_in_pack(struct packed_git *p,
153
153
uint32_t num , last , i , first = 0 ;
154
154
const struct object_id * current = NULL ;
155
155
156
- open_pack_index (p );
156
+ if (open_pack_index (p ) || !p -> num_objects )
157
+ return ;
158
+
157
159
num = p -> num_objects ;
158
160
last = num ;
159
161
while (first < last ) {
@@ -474,10 +476,104 @@ static unsigned msb(unsigned long val)
474
476
return r ;
475
477
}
476
478
477
- int find_unique_abbrev_r (char * hex , const unsigned char * sha1 , int len )
479
+ struct min_abbrev_data {
480
+ unsigned int init_len ;
481
+ unsigned int cur_len ;
482
+ char * hex ;
483
+ const unsigned char * hash ;
484
+ };
485
+
486
+ static inline char get_hex_char_from_oid (const struct object_id * oid ,
487
+ unsigned int pos )
478
488
{
479
- int status , exists ;
489
+ static const char hex [] = "0123456789abcdef" ;
480
490
491
+ if ((pos & 1 ) == 0 )
492
+ return hex [oid -> hash [pos >> 1 ] >> 4 ];
493
+ else
494
+ return hex [oid -> hash [pos >> 1 ] & 0xf ];
495
+ }
496
+
497
+ static int extend_abbrev_len (const struct object_id * oid , void * cb_data )
498
+ {
499
+ struct min_abbrev_data * mad = cb_data ;
500
+
501
+ unsigned int i = mad -> init_len ;
502
+ while (mad -> hex [i ] && mad -> hex [i ] == get_hex_char_from_oid (oid , i ))
503
+ i ++ ;
504
+
505
+ if (i < GIT_MAX_RAWSZ && i >= mad -> cur_len )
506
+ mad -> cur_len = i + 1 ;
507
+
508
+ return 0 ;
509
+ }
510
+
511
+ static void find_abbrev_len_for_pack (struct packed_git * p ,
512
+ struct min_abbrev_data * mad )
513
+ {
514
+ int match = 0 ;
515
+ uint32_t num , last , first = 0 ;
516
+ struct object_id oid ;
517
+
518
+ if (open_pack_index (p ) || !p -> num_objects )
519
+ return ;
520
+
521
+ num = p -> num_objects ;
522
+ last = num ;
523
+ while (first < last ) {
524
+ uint32_t mid = first + (last - first ) / 2 ;
525
+ const unsigned char * current ;
526
+ int cmp ;
527
+
528
+ current = nth_packed_object_sha1 (p , mid );
529
+ cmp = hashcmp (mad -> hash , current );
530
+ if (!cmp ) {
531
+ match = 1 ;
532
+ first = mid ;
533
+ break ;
534
+ }
535
+ if (cmp > 0 ) {
536
+ first = mid + 1 ;
537
+ continue ;
538
+ }
539
+ last = mid ;
540
+ }
541
+
542
+ /*
543
+ * first is now the position in the packfile where we would insert
544
+ * mad->hash if it does not exist (or the position of mad->hash if
545
+ * it does exist). Hence, we consider a maximum of three objects
546
+ * nearby for the abbreviation length.
547
+ */
548
+ mad -> init_len = 0 ;
549
+ if (!match ) {
550
+ nth_packed_object_oid (& oid , p , first );
551
+ extend_abbrev_len (& oid , mad );
552
+ } else if (first < num - 1 ) {
553
+ nth_packed_object_oid (& oid , p , first + 1 );
554
+ extend_abbrev_len (& oid , mad );
555
+ }
556
+ if (first > 0 ) {
557
+ nth_packed_object_oid (& oid , p , first - 1 );
558
+ extend_abbrev_len (& oid , mad );
559
+ }
560
+ mad -> init_len = mad -> cur_len ;
561
+ }
562
+
563
+ static void find_abbrev_len_packed (struct min_abbrev_data * mad )
564
+ {
565
+ struct packed_git * p ;
566
+
567
+ prepare_packed_git ();
568
+ for (p = packed_git ; p ; p = p -> next )
569
+ find_abbrev_len_for_pack (p , mad );
570
+ }
571
+
572
+ int find_unique_abbrev_r (char * hex , const unsigned char * sha1 , int len )
573
+ {
574
+ struct disambiguate_state ds ;
575
+ struct min_abbrev_data mad ;
576
+ struct object_id oid_ret ;
481
577
if (len < 0 ) {
482
578
unsigned long count = approximate_object_count ();
483
579
/*
@@ -503,19 +599,26 @@ int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len)
503
599
sha1_to_hex_r (hex , sha1 );
504
600
if (len == GIT_SHA1_HEXSZ || !len )
505
601
return GIT_SHA1_HEXSZ ;
506
- exists = has_sha1_file (sha1 );
507
- while (len < GIT_SHA1_HEXSZ ) {
508
- struct object_id oid_ret ;
509
- status = get_short_oid (hex , len , & oid_ret , GET_OID_QUIETLY );
510
- if (exists
511
- ? !status
512
- : status == SHORT_NAME_NOT_FOUND ) {
513
- hex [len ] = 0 ;
514
- return len ;
515
- }
516
- len ++ ;
517
- }
518
- return len ;
602
+
603
+ mad .init_len = len ;
604
+ mad .cur_len = len ;
605
+ mad .hex = hex ;
606
+ mad .hash = sha1 ;
607
+
608
+ find_abbrev_len_packed (& mad );
609
+
610
+ if (init_object_disambiguation (hex , mad .cur_len , & ds ) < 0 )
611
+ return -1 ;
612
+
613
+ ds .fn = extend_abbrev_len ;
614
+ ds .always_call_fn = 1 ;
615
+ ds .cb_data = (void * )& mad ;
616
+
617
+ find_short_object_filename (& ds );
618
+ (void )finish_object_disambiguation (& ds , & oid_ret );
619
+
620
+ hex [mad .cur_len ] = 0 ;
621
+ return mad .cur_len ;
519
622
}
520
623
521
624
const char * find_unique_abbrev (const unsigned char * sha1 , int len )
0 commit comments