Do not print 'dangling' for cat-file in case of ambiguity
The return values -1 and -2 from get_oid could mean two different things, depending on whether they were from an enum returned by get_tree_entry_follow_symlinks, or from a different code path. This caused 'dangling' to be printed from a git cat-file in the case of an ambiguous (-2) result. Unify the results of get_oid* and get_tree_entry_follow_symlinks to be one common type, with unambiguous values. Signed-off-by: David Turner <novalis@novalis.org> Reported-by: Eric Wong <e@80x24.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
David Turner committed
Jan 17, 2019 at 23:19 UTC
d1dd94b308607d0a37aa8a013fd20678956d3531
6 files changed
+62
-49
Documentation/git-cat-file.txt
+6
@@ -252,6 +252,12 @@ the repository, then `cat-file` will ignore any custom format and print:
252
<object> SP missing LF
253
------------
254
255
+If a name is specified that might refer to more than one object (an ambiguous short sha), then `cat-file` will ignore any custom format and print:
256
+
257
+------------
258
+<object> SP ambiguous LF
259
+------------
260
+
261
If --follow-symlinks is used, and a symlink in the repository points
262
outside the repository, then `cat-file` will ignore any custom format
263
and print:
builtin/cat-file.c
+4
-1
@@ -380,7 +380,7 @@ static void batch_one_object(const char *obj_name,
380
{
381
struct object_context ctx;
382
int flags = opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0;
383
- enum follow_symlinks_result result;
383
+ enum get_oid_result result;
384
385
result = get_oid_with_context(obj_name, flags, &data->oid, &ctx);
386
if (result != FOUND) {
@@ -388,6 +388,9 @@ static void batch_one_object(const char *obj_name,
388
case MISSING_OBJECT:
389
printf("%s missing\n", obj_name);
390
break;
391
+ case SHORT_NAME_AMBIGUOUS:
392
+ printf("%s ambiguous\n", obj_name);
393
+ break;
394
case DANGLING_SYMLINK:
395
printf("dangling %"PRIuMAX"\n%s\n",
396
(uintmax_t)strlen(obj_name), obj_name);
cache.h
+19
-1
@@ -1332,6 +1332,24 @@ struct object_context {
1332
GET_OID_TREE | GET_OID_TREEISH | \
1333
GET_OID_BLOB)
1334
1335
+enum get_oid_result {
1336
+ FOUND = 0,
1337
+ MISSING_OBJECT = -1, /* The requested object is missing */
1338
+ SHORT_NAME_AMBIGUOUS = -2,
1339
+ /* The following only apply when symlinks are followed */
1340
+ DANGLING_SYMLINK = -4, /*
1341
+ * The initial symlink is there, but
1342
+ * (transitively) points to a missing
1343
+ * in-tree file
1344
+ */
1345
+ SYMLINK_LOOP = -5,
1346
+ NOT_DIR = -6, /*
1347
+ * Somewhere along the symlink chain, a path is
1348
+ * requested which contains a file as a
1349
+ * non-final element.
1350
+ */
1351
+};
1352
+
1353
extern int get_oid(const char *str, struct object_id *oid);
1354
extern int get_oid_commit(const char *str, struct object_id *oid);
1355
extern int get_oid_committish(const char *str, struct object_id *oid);
@@ -1339,7 +1357,7 @@ extern int get_oid_tree(const char *str, struct object_id *oid);
1357
extern int get_oid_treeish(const char *str, struct object_id *oid);
1358
extern int get_oid_blob(const char *str, struct object_id *oid);
1359
extern void maybe_die_on_misspelt_object_name(const char *name, const char *prefix);
1342
-extern int get_oid_with_context(const char *str, unsigned flags, struct object_id *oid, struct object_context *oc);
1360
+extern enum get_oid_result get_oid_with_context(const char *str, unsigned flags, struct object_id *oid, struct object_context *oc);
1361
1362
1363
typedef int each_abbrev_fn(const struct object_id *oid, void *);
sha1-name.c
+30
-28
@@ -190,9 +190,6 @@ static void find_short_packed_object(struct disambiguate_state *ds)
190
unique_in_pack(p, ds);
191
}
192
193
-#define SHORT_NAME_NOT_FOUND (-1)
194
-#define SHORT_NAME_AMBIGUOUS (-2)
195
-
193
static int finish_object_disambiguation(struct disambiguate_state *ds,
194
struct object_id *oid)
195
{
@@ -200,7 +197,7 @@ static int finish_object_disambiguation(struct disambiguate_state *ds,
197
return SHORT_NAME_AMBIGUOUS;
198
199
if (!ds->candidate_exists)
203
- return SHORT_NAME_NOT_FOUND;
200
+ return MISSING_OBJECT;
201
202
if (!ds->candidate_checked)
203
/*
@@ -414,8 +411,9 @@ static int sort_ambiguous(const void *a, const void *b)
411
return a_type_sort > b_type_sort ? 1 : -1;
412
}
413
417
-static int get_short_oid(const char *name, int len, struct object_id *oid,
418
- unsigned flags)
414
+static enum get_oid_result get_short_oid(const char *name, int len,
415
+ struct object_id *oid,
416
+ unsigned flags)
417
{
418
int status;
419
struct disambiguate_state ds;
@@ -733,7 +731,7 @@ static inline int push_mark(const char *string, int len)
731
return at_mark(string, len, suffix, ARRAY_SIZE(suffix));
732
}
733
736
-static int get_oid_1(const char *name, int len, struct object_id *oid, unsigned lookup_flags);
734
+static enum get_oid_result get_oid_1(const char *name, int len, struct object_id *oid, unsigned lookup_flags);
735
static int interpret_nth_prior_checkout(const char *name, int namelen, struct strbuf *buf);
736
737
static int get_oid_basic(const char *str, int len, struct object_id *oid,
@@ -883,11 +881,12 @@ static int get_oid_basic(const char *str, int len, struct object_id *oid,
881
return 0;
882
}
883
886
-static int get_parent(const char *name, int len,
887
- struct object_id *result, int idx)
884
+static enum get_oid_result get_parent(const char *name, int len,
885
+ struct object_id *result, int idx)
886
{
887
struct object_id oid;
890
- int ret = get_oid_1(name, len, &oid, GET_OID_COMMITTISH);
888
+ enum get_oid_result ret = get_oid_1(name, len, &oid,
889
+ GET_OID_COMMITTISH);
890
struct commit *commit;
891
struct commit_list *p;
892
@@ -895,24 +894,25 @@ static int get_parent(const char *name, int len,
894
return ret;
895
commit = lookup_commit_reference(the_repository, &oid);
896
if (parse_commit(commit))
898
- return -1;
897
+ return MISSING_OBJECT;
898
if (!idx) {
899
oidcpy(result, &commit->object.oid);
901
- return 0;
900
+ return FOUND;
901
}
902
p = commit->parents;
903
while (p) {
904
if (!--idx) {
905
oidcpy(result, &p->item->object.oid);
907
- return 0;
906
+ return FOUND;
907
}
908
p = p->next;
909
}
911
- return -1;
910
+ return MISSING_OBJECT;
911
}
912
914
-static int get_nth_ancestor(const char *name, int len,
915
- struct object_id *result, int generation)
913
+static enum get_oid_result get_nth_ancestor(const char *name, int len,
914
+ struct object_id *result,
915
+ int generation)
916
{
917
struct object_id oid;
918
struct commit *commit;
@@ -923,15 +923,15 @@ static int get_nth_ancestor(const char *name, int len,
923
return ret;
924
commit = lookup_commit_reference(the_repository, &oid);
925
if (!commit)
926
- return -1;
926
+ return MISSING_OBJECT;
927
928
while (generation--) {
929
if (parse_commit(commit) || !commit->parents)
930
- return -1;
930
+ return MISSING_OBJECT;
931
commit = commit->parents->item;
932
}
933
oidcpy(result, &commit->object.oid);
934
- return 0;
934
+ return FOUND;
935
}
936
937
struct object *peel_to_type(const char *name, int namelen,
@@ -1077,7 +1077,9 @@ static int get_describe_name(const char *name, int len, struct object_id *oid)
1077
return -1;
1078
}
1079
1080
-static int get_oid_1(const char *name, int len, struct object_id *oid, unsigned lookup_flags)
1080
+static enum get_oid_result get_oid_1(const char *name, int len,
1081
+ struct object_id *oid,
1082
+ unsigned lookup_flags)
1083
{
1084
int ret, has_suffix;
1085
const char *cp;
@@ -1111,16 +1113,16 @@ static int get_oid_1(const char *name, int len, struct object_id *oid, unsigned
1113
1114
ret = peel_onion(name, len, oid, lookup_flags);
1115
if (!ret)
1114
- return 0;
1116
+ return FOUND;
1117
1118
ret = get_oid_basic(name, len, oid, lookup_flags);
1119
if (!ret)
1118
- return 0;
1120
+ return FOUND;
1121
1122
/* It could be describe output that is "SOMETHING-gXXXX" */
1123
ret = get_describe_name(name, len, oid);
1124
if (!ret)
1123
- return 0;
1125
+ return FOUND;
1126
1127
return get_short_oid(name, len, oid, lookup_flags);
1128
}
@@ -1664,11 +1666,11 @@ static char *resolve_relative_path(const char *rel)
1666
rel);
1667
}
1668
1667
-static int get_oid_with_context_1(const char *name,
1668
- unsigned flags,
1669
- const char *prefix,
1670
- struct object_id *oid,
1671
- struct object_context *oc)
1669
+static enum get_oid_result get_oid_with_context_1(const char *name,
1670
+ unsigned flags,
1671
+ const char *prefix,
1672
+ struct object_id *oid,
1673
+ struct object_context *oc)
1674
{
1675
int ret, bracket_depth;
1676
int namelen = strlen(name);
tree-walk.c
+2
-2
@@ -579,10 +579,10 @@ int get_tree_entry(const struct object_id *tree_oid, const char *name, struct ob
579
* with the sha1 of the found object, and *mode will hold the mode of
580
* the object.
581
*
582
- * See the code for enum follow_symlink_result for a description of
582
+ * See the code for enum get_oid_result for a description of
583
* the return values.
584
*/
585
-enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode)
585
+enum get_oid_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode)
586
{
587
int retval = MISSING_OBJECT;
588
struct dir_state *parents = NULL;
tree-walk.h
+1
-17
@@ -51,23 +51,7 @@ struct traverse_info;
51
typedef int (*traverse_callback_t)(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, struct traverse_info *);
52
int traverse_trees(struct index_state *istate, int n, struct tree_desc *t, struct traverse_info *info);
53
54
-enum follow_symlinks_result {
55
- FOUND = 0, /* This includes out-of-tree links */
56
- MISSING_OBJECT = -1, /* The initial symlink is missing */
57
- DANGLING_SYMLINK = -2, /*
58
- * The initial symlink is there, but
59
- * (transitively) points to a missing
60
- * in-tree file
61
- */
62
- SYMLINK_LOOP = -3,
63
- NOT_DIR = -4, /*
64
- * Somewhere along the symlink chain, a path is
65
- * requested which contains a file as a
66
- * non-final element.
67
- */
68
-};
69
-
70
-enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode);
54
+enum get_oid_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode);
55
56
struct traverse_info {
57
const char *traverse_path;