@@ -78,60 +78,69 @@ static int match_sha(unsigned len, const unsigned char *a, const unsigned char *
78
78
return 1 ;
79
79
}
80
80
81
+ static int unique_in_pack (int len ,
82
+ const unsigned char * match ,
83
+ struct packed_git * p ,
84
+ const unsigned char * * found_sha1 ,
85
+ int seen_so_far )
86
+ {
87
+ uint32_t num , last , i , first = 0 ;
88
+ const unsigned char * current = NULL ;
89
+
90
+ open_pack_index (p );
91
+ num = p -> num_objects ;
92
+ last = num ;
93
+ while (first < last ) {
94
+ uint32_t mid = (first + last ) / 2 ;
95
+ const unsigned char * current ;
96
+ int cmp ;
97
+
98
+ current = nth_packed_object_sha1 (p , mid );
99
+ cmp = hashcmp (match , current );
100
+ if (!cmp ) {
101
+ first = mid ;
102
+ break ;
103
+ }
104
+ if (cmp > 0 ) {
105
+ first = mid + 1 ;
106
+ continue ;
107
+ }
108
+ last = mid ;
109
+ }
110
+
111
+ /*
112
+ * At this point, "first" is the location of the lowest object
113
+ * with an object name that could match "match". See if we have
114
+ * 0, 1 or more objects that actually match(es).
115
+ */
116
+ for (i = first ; i < num ; i ++ ) {
117
+ current = nth_packed_object_sha1 (p , first );
118
+ if (!match_sha (len , match , current ))
119
+ break ;
120
+
121
+ /* current matches */
122
+ if (!seen_so_far ) {
123
+ * found_sha1 = current ;
124
+ seen_so_far ++ ;
125
+ } else if (seen_so_far ) {
126
+ /* is it the same as the one previously found elsewhere? */
127
+ if (hashcmp (* found_sha1 , current ))
128
+ return 2 ; /* definitely not unique */
129
+ }
130
+ }
131
+ return seen_so_far ;
132
+ }
133
+
81
134
static int find_short_packed_object (int len , const unsigned char * match , unsigned char * sha1 )
82
135
{
83
136
struct packed_git * p ;
84
137
const unsigned char * found_sha1 = NULL ;
85
138
int found = 0 ;
86
139
87
140
prepare_packed_git ();
88
- for (p = packed_git ; p && found < 2 ; p = p -> next ) {
89
- uint32_t num , last ;
90
- uint32_t first = 0 ;
91
- open_pack_index (p );
92
- num = p -> num_objects ;
93
- last = num ;
94
- while (first < last ) {
95
- uint32_t mid = (first + last ) / 2 ;
96
- const unsigned char * current ;
97
- int cmp ;
98
-
99
- current = nth_packed_object_sha1 (p , mid );
100
- cmp = hashcmp (match , current );
101
- if (!cmp ) {
102
- first = mid ;
103
- break ;
104
- }
105
- if (cmp > 0 ) {
106
- first = mid + 1 ;
107
- continue ;
108
- }
109
- last = mid ;
110
- }
111
- if (first < num ) {
112
- const unsigned char * current , * next ;
113
- current = nth_packed_object_sha1 (p , first );
114
- if (match_sha (len , match , current )) {
115
- next = nth_packed_object_sha1 (p , first + 1 );
116
- if (!next || !match_sha (len , match , next )) {
117
- /* unique within this pack */
118
- if (!found ) {
119
- found_sha1 = current ;
120
- found ++ ;
121
- }
122
- else if (hashcmp (found_sha1 , current )) {
123
- found = 2 ;
124
- break ;
125
- }
126
- }
127
- else {
128
- /* not even unique within this pack */
129
- found = 2 ;
130
- break ;
131
- }
132
- }
133
- }
134
- }
141
+ for (p = packed_git ; p && found < 2 ; p = p -> next )
142
+ found = unique_in_pack (len , match , p , & found_sha1 , found );
143
+
135
144
if (found == 1 )
136
145
hashcpy (sha1 , found_sha1 );
137
146
return found ;
0 commit comments