diff options
-rw-r--r-- | cache.h | 3 | ||||
-rw-r--r-- | sha1_name.c | 57 |
2 files changed, 41 insertions, 19 deletions
@@ -499,6 +499,9 @@ extern void *read_object_with_reference(const unsigned char *sha1, unsigned long *size, unsigned char *sha1_ret); +extern struct object *peel_to_type(const char *name, int namelen, + struct object *o, enum object_type); + enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, diff --git a/sha1_name.c b/sha1_name.c index ed3c867d6..739f1b2d4 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -423,6 +423,37 @@ static int get_nth_ancestor(const char *name, int len, return 0; } +struct object *peel_to_type(const char *name, int namelen, + struct object *o, enum object_type expected_type) +{ + if (name && !namelen) + namelen = strlen(name); + if (!o) { + unsigned char sha1[20]; + if (get_sha1_1(name, namelen, sha1)) + return NULL; + o = parse_object(sha1); + } + while (1) { + if (!o || (!o->parsed && !parse_object(o->sha1))) + return NULL; + if (o->type == expected_type) + return o; + if (o->type == OBJ_TAG) + o = ((struct tag*) o)->tagged; + else if (o->type == OBJ_COMMIT) + o = &(((struct commit *) o)->tree->object); + else { + if (name) + error("%.*s: expected %s type, but the object " + "dereferences to %s type", + namelen, name, typename(expected_type), + typename(o->type)); + return NULL; + } + } +} + static int peel_onion(const char *name, int len, unsigned char *sha1) { unsigned char outer[20]; @@ -474,29 +505,17 @@ static int peel_onion(const char *name, int len, unsigned char *sha1) hashcpy(sha1, o->sha1); } else { - /* At this point, the syntax look correct, so + /* + * At this point, the syntax look correct, so * if we do not get the needed object, we should * barf. */ - - while (1) { - if (!o || (!o->parsed && !parse_object(o->sha1))) - return -1; - if (o->type == expected_type) { - hashcpy(sha1, o->sha1); - return 0; - } - if (o->type == OBJ_TAG) - o = ((struct tag*) o)->tagged; - else if (o->type == OBJ_COMMIT) - o = &(((struct commit *) o)->tree->object); - else - return error("%.*s: expected %s type, but the object dereferences to %s type", - len, name, typename(expected_type), - typename(o->type)); - if (!o->parsed) - parse_object(o->sha1); + o = peel_to_type(name, len, o, expected_type); + if (o) { + hashcpy(sha1, o->sha1); + return 0; } + return -1; } return 0; } |