Skip to content

Commit 0016043

Browse files
peffgitster
authored andcommitted
get_short_sha1: refactor init of disambiguation code
The disambiguation machinery has two callers: get_short_sha1 and for_each_abbrev. Both need to repeat much of the same setup: declaring buffers, sanity-checking lengths, preparing the prefixes, etc. Let's pull that into a single init function so we can avoid repeating ourselves. Pulling the buffers into the "struct disambiguate_state" isn't strictly necessary, but it does make things simpler for the callers, who no longer have to worry about sizing them correctly (i.e., it's an implicit requirement that the caller provide 20- and 40-byte buffers). And while we're touching this code, we can convert any magic-number sizes to the more modern GIT_SHA1_* constants. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5d5def2 commit 0016043

File tree

1 file changed

+35
-44
lines changed

1 file changed

+35
-44
lines changed

sha1_name.c

Lines changed: 35 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ static int get_sha1_oneline(const char *, unsigned char *, struct commit_list *)
1313
typedef int (*disambiguate_hint_fn)(const unsigned char *, void *);
1414

1515
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+
1620
disambiguate_hint_fn fn;
1721
void *cb_data;
18-
unsigned char candidate[20];
22+
unsigned char candidate[GIT_SHA1_RAWSZ];
1923
unsigned candidate_exists:1;
2024
unsigned candidate_checked:1;
2125
unsigned candidate_ok:1;
@@ -72,10 +76,10 @@ static void update_candidates(struct disambiguate_state *ds, const unsigned char
7276
/* otherwise, current can be discarded and candidate is still good */
7377
}
7478

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)
7680
{
7781
struct alternate_object_database *alt;
78-
char hex[40];
82+
char hex[GIT_SHA1_HEXSZ];
7983
static struct alternate_object_database *fakeent;
8084

8185
if (!fakeent) {
@@ -95,15 +99,15 @@ static void find_short_object_filename(int len, const char *hex_pfx, struct disa
9599
}
96100
fakeent->next = alt_odb_list;
97101

98-
xsnprintf(hex, sizeof(hex), "%.2s", hex_pfx);
102+
xsnprintf(hex, sizeof(hex), "%.2s", ds->hex_pfx);
99103
for (alt = fakeent; alt && !ds->ambiguous; alt = alt->next) {
100104
struct dirent *de;
101105
DIR *dir;
102106
/*
103107
* every alt_odb struct has 42 extra bytes after the base
104108
* for exactly this purpose
105109
*/
106-
xsnprintf(alt->name, 42, "%.2s/", hex_pfx);
110+
xsnprintf(alt->name, 42, "%.2s/", ds->hex_pfx);
107111
dir = opendir(alt->base);
108112
if (!dir)
109113
continue;
@@ -113,7 +117,7 @@ static void find_short_object_filename(int len, const char *hex_pfx, struct disa
113117

114118
if (strlen(de->d_name) != 38)
115119
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))
117121
continue;
118122
memcpy(hex + 2, de->d_name, 38);
119123
if (!get_sha1_hex(hex, sha1))
@@ -138,9 +142,7 @@ static int match_sha(unsigned len, const unsigned char *a, const unsigned char *
138142
return 1;
139143
}
140144

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,
144146
struct disambiguate_state *ds)
145147
{
146148
uint32_t num, last, i, first = 0;
@@ -155,7 +157,7 @@ static void unique_in_pack(int len,
155157
int cmp;
156158

157159
current = nth_packed_object_sha1(p, mid);
158-
cmp = hashcmp(bin_pfx, current);
160+
cmp = hashcmp(ds->bin_pfx, current);
159161
if (!cmp) {
160162
first = mid;
161163
break;
@@ -174,20 +176,19 @@ static void unique_in_pack(int len,
174176
*/
175177
for (i = first; i < num && !ds->ambiguous; i++) {
176178
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))
178180
break;
179181
update_candidates(ds, current);
180182
}
181183
}
182184

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)
185186
{
186187
struct packed_git *p;
187188

188189
prepare_packed_git();
189190
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);
191192
}
192193

193194
#define SHORT_NAME_NOT_FOUND (-1)
@@ -281,14 +282,17 @@ static int disambiguate_blob_only(const unsigned char *sha1, void *cb_data_unuse
281282
return kind == OBJ_BLOB;
282283
}
283284

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)
287287
{
288288
int i;
289289

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+
292296
for (i = 0; i < len ;i++) {
293297
unsigned char c = name[i];
294298
unsigned char val;
@@ -302,32 +306,27 @@ static int prepare_prefixes(const char *name, int len,
302306
}
303307
else
304308
return -1;
305-
hex_pfx[i] = c;
309+
ds->hex_pfx[i] = c;
306310
if (!(i & 1))
307311
val <<= 4;
308-
bin_pfx[i >> 1] |= val;
312+
ds->bin_pfx[i >> 1] |= val;
309313
}
314+
315+
ds->len = len;
316+
prepare_alt_odb();
310317
return 0;
311318
}
312319

313320
static int get_short_sha1(const char *name, int len, unsigned char *sha1,
314321
unsigned flags)
315322
{
316323
int status;
317-
char hex_pfx[40];
318-
unsigned char bin_pfx[20];
319324
struct disambiguate_state ds;
320325
int quietly = !!(flags & GET_SHA1_QUIETLY);
321326

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)
325328
return -1;
326329

327-
prepare_alt_odb();
328-
329-
memset(&ds, 0, sizeof(ds));
330-
331330
if (HAS_MULTI_BITS(flags & GET_SHA1_DISAMBIGUATORS))
332331
die("BUG: multiple get_short_sha1 disambiguator flags");
333332

@@ -342,36 +341,28 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1,
342341
else if (flags & GET_SHA1_BLOB)
343342
ds.fn = disambiguate_blob_only;
344343

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);
347346
status = finish_object_disambiguation(&ds, sha1);
348347

349348
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);
351350
return status;
352351
}
353352

354353
int for_each_abbrev(const char *prefix, each_abbrev_fn fn, void *cb_data)
355354
{
356-
char hex_pfx[40];
357-
unsigned char bin_pfx[20];
358355
struct disambiguate_state ds;
359-
int len = strlen(prefix);
360356

361-
if (len < MINIMUM_ABBREV || len > 40)
357+
if (init_object_disambiguation(prefix, strlen(prefix), &ds) < 0)
362358
return -1;
363-
if (prepare_prefixes(prefix, len, bin_pfx, hex_pfx) < 0)
364-
return -1;
365-
366-
prepare_alt_odb();
367359

368-
memset(&ds, 0, sizeof(ds));
369360
ds.always_call_fn = 1;
370361
ds.cb_data = cb_data;
371362
ds.fn = fn;
372363

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);
375366
return ds.ambiguous;
376367
}
377368

0 commit comments

Comments
 (0)