Skip to content

Commit daba53a

Browse files
committed
sha1_name.c: add support for disambiguating other types
This teaches the revision parser that in "$name:$path" (used for a blob object name), "$name" must be a tree-ish. There are many more places where we know what types of objects are called for. This patch adds support for "commit", "treeish", "tree", and "blob", which could be used in the following contexts: - "git apply --build-fake-ancestor" reads the "index" lines from the patch; they must name blob objects (not even "blob-ish"); - "git commit-tree" reads a tree object name (not "tree-ish"), and zero or more commit object names (not "committish"); - "git reset $rev" wants a committish; "git reset $rev -- $path" wants a treeish. They will come in later patches in the series. Signed-off-by: Junio C Hamano <[email protected]>
1 parent d5f6b1d commit daba53a

File tree

3 files changed

+76
-5
lines changed

3 files changed

+76
-5
lines changed

cache.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -811,13 +811,20 @@ struct object_context {
811811
unsigned mode;
812812
};
813813

814-
#define GET_SHA1_QUIETLY 01
815-
#define GET_SHA1_COMMIT 02
816-
#define GET_SHA1_COMMITTISH 04
814+
#define GET_SHA1_QUIETLY 01
815+
#define GET_SHA1_COMMIT 02
816+
#define GET_SHA1_COMMITTISH 04
817+
#define GET_SHA1_TREE 010
818+
#define GET_SHA1_TREEISH 020
819+
#define GET_SHA1_BLOB 040
817820
#define GET_SHA1_ONLY_TO_DIE 04000
818821

819822
extern int get_sha1(const char *str, unsigned char *sha1);
823+
extern int get_sha1_commit(const char *str, unsigned char *sha1);
820824
extern int get_sha1_committish(const char *str, unsigned char *sha1);
825+
extern int get_sha1_tree(const char *str, unsigned char *sha1);
826+
extern int get_sha1_treeish(const char *str, unsigned char *sha1);
827+
extern int get_sha1_blob(const char *str, unsigned char *sha1);
821828
extern void maybe_die_on_misspelt_object_name(const char *name, const char *prefix);
822829
extern int get_sha1_with_context(const char *str, unsigned flags, unsigned char *sha1, struct object_context *orc);
823830

sha1_name.c

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,36 @@ static int disambiguate_committish_only(const unsigned char *sha1, void *cb_data
242242
return 0;
243243
}
244244

245+
static int disambiguate_tree_only(const unsigned char *sha1, void *cb_data_unused)
246+
{
247+
int kind = sha1_object_info(sha1, NULL);
248+
return kind == OBJ_TREE;
249+
}
250+
251+
static int disambiguate_treeish_only(const unsigned char *sha1, void *cb_data_unused)
252+
{
253+
struct object *obj;
254+
int kind;
255+
256+
kind = sha1_object_info(sha1, NULL);
257+
if (kind == OBJ_TREE || kind == OBJ_COMMIT)
258+
return 1;
259+
if (kind != OBJ_TAG)
260+
return 0;
261+
262+
/* We need to do this the hard way... */
263+
obj = deref_tag(lookup_object(sha1), NULL, 0);
264+
if (obj && (obj->type == OBJ_TREE || obj->type == OBJ_COMMIT))
265+
return 1;
266+
return 0;
267+
}
268+
269+
static int disambiguate_blob_only(const unsigned char *sha1, void *cb_data_unused)
270+
{
271+
int kind = sha1_object_info(sha1, NULL);
272+
return kind == OBJ_BLOB;
273+
}
274+
245275
static int get_short_sha1(const char *name, int len, unsigned char *sha1,
246276
unsigned flags)
247277
{
@@ -281,6 +311,12 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1,
281311
ds.fn = disambiguate_commit_only;
282312
else if (flags & GET_SHA1_COMMITTISH)
283313
ds.fn = disambiguate_committish_only;
314+
else if (flags & GET_SHA1_TREE)
315+
ds.fn = disambiguate_tree_only;
316+
else if (flags & GET_SHA1_TREEISH)
317+
ds.fn = disambiguate_treeish_only;
318+
else if (flags & GET_SHA1_BLOB)
319+
ds.fn = disambiguate_blob_only;
284320

285321
find_short_object_filename(len, hex_pfx, &ds);
286322
find_short_packed_object(len, bin_pfx, &ds);
@@ -1016,6 +1052,34 @@ int get_sha1_committish(const char *name, unsigned char *sha1)
10161052
sha1, &unused);
10171053
}
10181054

1055+
int get_sha1_treeish(const char *name, unsigned char *sha1)
1056+
{
1057+
struct object_context unused;
1058+
return get_sha1_with_context(name, GET_SHA1_TREEISH,
1059+
sha1, &unused);
1060+
}
1061+
1062+
int get_sha1_commit(const char *name, unsigned char *sha1)
1063+
{
1064+
struct object_context unused;
1065+
return get_sha1_with_context(name, GET_SHA1_COMMIT,
1066+
sha1, &unused);
1067+
}
1068+
1069+
int get_sha1_tree(const char *name, unsigned char *sha1)
1070+
{
1071+
struct object_context unused;
1072+
return get_sha1_with_context(name, GET_SHA1_TREE,
1073+
sha1, &unused);
1074+
}
1075+
1076+
int get_sha1_blob(const char *name, unsigned char *sha1)
1077+
{
1078+
struct object_context unused;
1079+
return get_sha1_with_context(name, GET_SHA1_BLOB,
1080+
sha1, &unused);
1081+
}
1082+
10191083
/* Must be called only when object_name:filename doesn't exist. */
10201084
static void diagnose_invalid_sha1_path(const char *prefix,
10211085
const char *filename,
@@ -1221,7 +1285,7 @@ static int get_sha1_with_context_1(const char *name,
12211285
strncpy(object_name, name, cp-name);
12221286
object_name[cp-name] = '\0';
12231287
}
1224-
if (!get_sha1_1(name, cp-name, tree_sha1, 0)) {
1288+
if (!get_sha1_1(name, cp-name, tree_sha1, GET_SHA1_TREEISH)) {
12251289
const char *filename = cp+1;
12261290
char *new_filename = NULL;
12271291

t/t1512-rev-parse-disambiguation.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ test_expect_success 'warn ambiguity when no candidate matches type hint' '
4545
grep "short SHA1 000000000 is ambiguous" actual
4646
'
4747

48-
test_expect_failure 'disambiguate tree-ish' '
48+
test_expect_success 'disambiguate tree-ish' '
4949
# feed tree-ish in an unambiguous way
5050
git rev-parse --verify 0000000000cdc:a0blgqsjc &&
5151

0 commit comments

Comments
 (0)