Skip to content

Commit 66c22ba

Browse files
committed
Merge branch 'jk/ambiguous-short-object-names'
When given an abbreviated object name that is not (or more realistically, "no longer") unique, we gave a fatal error "ambiguous argument". This error is now accompanied by hints that lists the objects that begins with the given prefix. During the course of development of this new feature, numerous minor bugs were uncovered and corrected, the most notable one of which is that we gave "short SHA1 xxxx is ambiguous." twice without good reason. * jk/ambiguous-short-object-names: get_short_sha1: make default disambiguation configurable get_short_sha1: list ambiguous objects on error for_each_abbrev: drop duplicate objects sha1_array: let callbacks interrupt iteration get_short_sha1: mark ambiguity error for translation get_short_sha1: NUL-terminate hex prefix get_short_sha1: refactor init of disambiguation code get_short_sha1: parse tags when looking for treeish get_sha1: propagate flags to child functions get_sha1: avoid repeating ourselves via ONLY_TO_DIE get_sha1: detect buggy calls with multiple disambiguators
2 parents 0cf3611 + 5b33cb1 commit 66c22ba

11 files changed

+250
-65
lines changed

Documentation/technical/api-sha1-array.txt

+6-2
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,20 @@ Functions
3838
`sha1_array_for_each_unique`::
3939
Efficiently iterate over each unique element of the list,
4040
executing the callback function for each one. If the array is
41-
not sorted, this function has the side effect of sorting it.
41+
not sorted, this function has the side effect of sorting it. If
42+
the callback returns a non-zero value, the iteration ends
43+
immediately and the callback's return is propagated; otherwise,
44+
0 is returned.
4245

4346
Examples
4447
--------
4548

4649
-----------------------------------------
47-
void print_callback(const unsigned char sha1[20],
50+
int print_callback(const unsigned char sha1[20],
4851
void *data)
4952
{
5053
printf("%s\n", sha1_to_hex(sha1));
54+
return 0; /* always continue */
5155
}
5256

5357
void some_func(void)

builtin/cat-file.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,12 @@ struct object_cb_data {
401401
struct expand_data *expand;
402402
};
403403

404-
static void batch_object_cb(const unsigned char sha1[20], void *vdata)
404+
static int batch_object_cb(const unsigned char sha1[20], void *vdata)
405405
{
406406
struct object_cb_data *data = vdata;
407407
hashcpy(data->expand->oid.hash, sha1);
408408
batch_object_write(NULL, data->opt, data->expand);
409+
return 0;
409410
}
410411

411412
static int batch_loose_object(const unsigned char *sha1,

builtin/receive-pack.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,10 @@ static int show_ref_cb(const char *path_full, const struct object_id *oid,
268268
return 0;
269269
}
270270

271-
static void show_one_alternate_sha1(const unsigned char sha1[20], void *unused)
271+
static int show_one_alternate_sha1(const unsigned char sha1[20], void *unused)
272272
{
273273
show_ref(".have", sha1);
274+
return 0;
274275
}
275276

276277
static void collect_one_alternate_ref(const struct ref *ref, void *data)

cache.h

+7
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,11 @@ struct object_context {
12061206
#define GET_SHA1_FOLLOW_SYMLINKS 0100
12071207
#define GET_SHA1_ONLY_TO_DIE 04000
12081208

1209+
#define GET_SHA1_DISAMBIGUATORS \
1210+
(GET_SHA1_COMMIT | GET_SHA1_COMMITTISH | \
1211+
GET_SHA1_TREE | GET_SHA1_TREEISH | \
1212+
GET_SHA1_BLOB)
1213+
12091214
extern int get_sha1(const char *str, unsigned char *sha1);
12101215
extern int get_sha1_commit(const char *str, unsigned char *sha1);
12111216
extern int get_sha1_committish(const char *str, unsigned char *sha1);
@@ -1220,6 +1225,8 @@ extern int get_oid(const char *str, struct object_id *oid);
12201225
typedef int each_abbrev_fn(const unsigned char *sha1, void *);
12211226
extern int for_each_abbrev(const char *prefix, each_abbrev_fn, void *);
12221227

1228+
extern int set_disambiguate_hint_config(const char *var, const char *value);
1229+
12231230
/*
12241231
* Try to read a SHA1 in hexadecimal format from the 40 characters
12251232
* starting at hex. Write the 20-byte result to sha1 in binary form.

config.c

+3
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,9 @@ static int git_default_core_config(const char *var, const char *value)
841841
return 0;
842842
}
843843

844+
if (!strcmp(var, "core.disambiguate"))
845+
return set_disambiguate_hint_config(var, value);
846+
844847
if (!strcmp(var, "core.loosecompression")) {
845848
int level = git_config_int(var, value);
846849
if (level == -1)

sha1-array.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void sha1_array_clear(struct sha1_array *array)
4242
array->sorted = 0;
4343
}
4444

45-
void sha1_array_for_each_unique(struct sha1_array *array,
45+
int sha1_array_for_each_unique(struct sha1_array *array,
4646
for_each_sha1_fn fn,
4747
void *data)
4848
{
@@ -52,8 +52,12 @@ void sha1_array_for_each_unique(struct sha1_array *array,
5252
sha1_array_sort(array);
5353

5454
for (i = 0; i < array->nr; i++) {
55+
int ret;
5556
if (i > 0 && !hashcmp(array->sha1[i], array->sha1[i-1]))
5657
continue;
57-
fn(array->sha1[i], data);
58+
ret = fn(array->sha1[i], data);
59+
if (ret)
60+
return ret;
5861
}
62+
return 0;
5963
}

sha1-array.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ void sha1_array_append(struct sha1_array *array, const unsigned char *sha1);
1414
int sha1_array_lookup(struct sha1_array *array, const unsigned char *sha1);
1515
void sha1_array_clear(struct sha1_array *array);
1616

17-
typedef void (*for_each_sha1_fn)(const unsigned char sha1[20],
18-
void *data);
19-
void sha1_array_for_each_unique(struct sha1_array *array,
20-
for_each_sha1_fn fn,
17+
typedef int (*for_each_sha1_fn)(const unsigned char sha1[20],
2118
void *data);
19+
int sha1_array_for_each_unique(struct sha1_array *array,
20+
for_each_sha1_fn fn,
21+
void *data);
2222

2323
#endif /* SHA1_ARRAY_H */

0 commit comments

Comments
 (0)