13
typedef int (*disambiguate_hint_fn)(const unsigned char *, void *);
14
15
struct disambiguate_state {
16
+ int len; /* length of prefix in hex chars */
17
+ char hex_pfx[GIT_SHA1_HEXSZ];
18
+ unsigned char bin_pfx[GIT_SHA1_RAWSZ];
19
+
20
disambiguate_hint_fn fn;
21
void *cb_data;
18
- unsigned char candidate[20];
22
+ unsigned char candidate[GIT_SHA1_RAWSZ];
23
unsigned candidate_exists:1;
24
unsigned candidate_checked:1;
25
unsigned candidate_ok:1;
76
/* otherwise, current can be discarded and candidate is still good */
77
}
78
75
-static void find_short_object_filename(int len, const char *hex_pfx, struct disambiguate_state *ds)
79
+static void find_short_object_filename(struct disambiguate_state *ds)
80
{
81
struct alternate_object_database *alt;
78
- char hex[40];
82
+ char hex[GIT_SHA1_HEXSZ];
83
static struct alternate_object_database *fakeent;
84
85
if (!fakeent) {
99
}
100
fakeent->next = alt_odb_list;
101
98
- xsnprintf(hex, sizeof(hex), "%.2s", hex_pfx);
102
+ xsnprintf(hex, sizeof(hex), "%.2s", ds->hex_pfx);
103
for (alt = fakeent; alt && !ds->ambiguous; alt = alt->next) {
104
struct dirent *de;
105
DIR *dir;
107
* every alt_odb struct has 42 extra bytes after the base
108
* for exactly this purpose
109
*/
106
- xsnprintf(alt->name, 42, "%.2s/", hex_pfx);
110
+ xsnprintf(alt->name, 42, "%.2s/", ds->hex_pfx);
111
dir = opendir(alt->base);
112
if (!dir)
113
continue;
117
118
if (strlen(de->d_name) != 38)
119
continue;
116
- if (memcmp(de->d_name, hex_pfx + 2, len - 2))
120
+ if (memcmp(de->d_name, ds->hex_pfx + 2, ds->len - 2))
121
continue;
122
memcpy(hex + 2, de->d_name, 38);
123
if (!get_sha1_hex(hex, sha1))
142
return 1;
143
}
144
141
-static void unique_in_pack(int len,
142
- const unsigned char *bin_pfx,
143
- struct packed_git *p,
145
+static void unique_in_pack(struct packed_git *p,
146
struct disambiguate_state *ds)
147
{
148
uint32_t num, last, i, first = 0;
157
int cmp;
158
159
current = nth_packed_object_sha1(p, mid);
158
- cmp = hashcmp(bin_pfx, current);
160
+ cmp = hashcmp(ds->bin_pfx, current);
161
if (!cmp) {
162
first = mid;
163
break;
176
*/
177
for (i = first; i < num && !ds->ambiguous; i++) {
178
current = nth_packed_object_sha1(p, i);
177
- if (!match_sha(len, bin_pfx, current))
179
+ if (!match_sha(ds->len, ds->bin_pfx, current))
180
break;
181
update_candidates(ds, current);
182
}
183
}
184
183
-static void find_short_packed_object(int len, const unsigned char *bin_pfx,
184
- struct disambiguate_state *ds)
185
+static void find_short_packed_object(struct disambiguate_state *ds)
186
{
187
struct packed_git *p;
188
189
prepare_packed_git();
190
for (p = packed_git; p && !ds->ambiguous; p = p->next)
190
- unique_in_pack(len, bin_pfx, p, ds);
191
+ unique_in_pack(p, ds);
192
}
193
194
#define SHORT_NAME_NOT_FOUND (-1)
282
return kind == OBJ_BLOB;
283
}
284
284
-static int prepare_prefixes(const char *name, int len,
285
- unsigned char *bin_pfx,
286
- char *hex_pfx)
285
+static int init_object_disambiguation(const char *name, int len,
286
+ struct disambiguate_state *ds)
287
{
288
int i;
289
290
- hashclr(bin_pfx);
291
- memset(hex_pfx, 'x', 40);
290
+ if (len < MINIMUM_ABBREV || len > GIT_SHA1_HEXSZ)
291
+ return -1;
292
+
293
+ memset(ds, 0, sizeof(*ds));
294
+ memset(ds->hex_pfx, 'x', GIT_SHA1_HEXSZ);
295
+
296
for (i = 0; i < len ;i++) {
297
unsigned char c = name[i];
298
unsigned char val;
306
}
307
else
308
return -1;
305
- hex_pfx[i] = c;
309
+ ds->hex_pfx[i] = c;
310
if (!(i & 1))
311
val <<= 4;
308
- bin_pfx[i >> 1] |= val;
312
+ ds->bin_pfx[i >> 1] |= val;
313
}
314
+
315
+ ds->len = len;
316
+ prepare_alt_odb();
317
return 0;
318
}
319
321
unsigned flags)
322
{
323
int status;
317
- char hex_pfx[40];
318
- unsigned char bin_pfx[20];
324
struct disambiguate_state ds;
325
int quietly = !!(flags & GET_SHA1_QUIETLY);
326
322
- if (len < MINIMUM_ABBREV || len > 40)
323
- return -1;
324
- if (prepare_prefixes(name, len, bin_pfx, hex_pfx) < 0)
327
+ if (init_object_disambiguation(name, len, &ds) < 0)
328
return -1;
329
327
- prepare_alt_odb();
328
-
329
- memset(&ds, 0, sizeof(ds));
330
-
330
if (HAS_MULTI_BITS(flags & GET_SHA1_DISAMBIGUATORS))
331
die("BUG: multiple get_short_sha1 disambiguator flags");
332
341
else if (flags & GET_SHA1_BLOB)
342
ds.fn = disambiguate_blob_only;
343
345
- find_short_object_filename(len, hex_pfx, &ds);
346
- find_short_packed_object(len, bin_pfx, &ds);
344
+ find_short_object_filename(&ds);
345
+ find_short_packed_object(&ds);
346
status = finish_object_disambiguation(&ds, sha1);
347
348
if (!quietly && (status == SHORT_NAME_AMBIGUOUS))
350
- return error("short SHA1 %.*s is ambiguous.", len, hex_pfx);
349
+ return error("short SHA1 %.*s is ambiguous.", ds.len, ds.hex_pfx);
350
return status;
351
}
352
353
int for_each_abbrev(const char *prefix, each_abbrev_fn fn, void *cb_data)
354
{
356
- char hex_pfx[40];
357
- unsigned char bin_pfx[20];
355
struct disambiguate_state ds;
359
- int len = strlen(prefix);
356
361
- if (len < MINIMUM_ABBREV || len > 40)
357
+ if (init_object_disambiguation(prefix, strlen(prefix), &ds) < 0)
358
return -1;
363
- if (prepare_prefixes(prefix, len, bin_pfx, hex_pfx) < 0)
364
- return -1;
365
-
366
- prepare_alt_odb();
359
368
- memset(&ds, 0, sizeof(ds));
360
ds.always_call_fn = 1;
361
ds.cb_data = cb_data;
362
ds.fn = fn;
363
373
- find_short_object_filename(len, hex_pfx, &ds);
374
- find_short_packed_object(len, bin_pfx, &ds);
364
+ find_short_object_filename(&ds);
365
+ find_short_packed_object(&ds);
366
return ds.ambiguous;
367
}
368