From 75aa26d34c4a80142512bd980a416b0fb30044c1 Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Tue, 3 Sep 2013 15:50:16 -0400 Subject: peel_onion(): add support for ^{tag} Complete the ^{} family of object descriptors by having ^{tag} dereference until a tag object is found (or fail if unable). At first glance this may not seem very useful, as commits, trees, and blobs cannot be peeled to a tag, and a tag would just peel to itself. However, this can be used to ensure that names a tag object: $ git rev-parse --verify v1.8.4^{tag} 04f013dc38d7512eadb915eba22efc414f18b869 $ git rev-parse --verify master^{tag} error: master^{tag}: expected tag type, but the object dereferences to tree type fatal: Needed a single revision Users can already ensure that is a tag object by checking the output of 'git cat-file -t ', but: * users may expect ^{tag} to exist given that ^{commit}, ^{tree}, and ^{blob} all exist * this syntax is more convenient/natural in some circumstances Signed-off-by: Richard Hansen Signed-off-by: Junio C Hamano --- sha1_name.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sha1_name.c') diff --git a/sha1_name.c b/sha1_name.c index 65ad066d9..6dc496deb 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -679,6 +679,8 @@ static int peel_onion(const char *name, int len, unsigned char *sha1) sp++; /* beginning of type name, or closing brace for empty */ if (!strncmp(commit_type, sp, 6) && sp[6] == '}') expected_type = OBJ_COMMIT; + else if (!strncmp(tag_type, sp, 3) && sp[3] == '}') + expected_type = OBJ_TAG; else if (!strncmp(tree_type, sp, 4) && sp[4] == '}') expected_type = OBJ_TREE; else if (!strncmp(blob_type, sp, 4) && sp[4] == '}') -- cgit v1.2.1 From c969b6a18d1cde3ffb8a5ca5cd45a57052c2cc95 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Tue, 3 Sep 2013 16:27:30 -0400 Subject: peel_onion: do not assume length of x_type globals When we are parsing "rev^{foo}", we check "foo" against the various global type strings, like "commit_type", "tree_type", etc. This is nicely abstracted, but then we destroy the abstraction completely by using magic numbers that must match the length of the type strings. We could avoid these magic numbers by using skip_prefix. But taking a step back, we can realize that using the "commit_type" global is not really buying us anything. It is not ever going to change from being "commit" without causing severe breakage to existing uses. And even if it did change for some crazy reason, we would want to evaluate its effects on the "rev^{}" syntax, anyway. Let's just switch these to using a custom string literal, as we do for "rev^{object}". The resulting code is more robust to changes in the type strings, and is more readable. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- sha1_name.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sha1_name.c') diff --git a/sha1_name.c b/sha1_name.c index 6dc496deb..2f6e5abaa 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -677,13 +677,13 @@ static int peel_onion(const char *name, int len, unsigned char *sha1) return -1; sp++; /* beginning of type name, or closing brace for empty */ - if (!strncmp(commit_type, sp, 6) && sp[6] == '}') + if (!prefixcmp(sp, "commit}")) expected_type = OBJ_COMMIT; - else if (!strncmp(tag_type, sp, 3) && sp[3] == '}') + else if (!prefixcmp(sp, "tag}")) expected_type = OBJ_TAG; - else if (!strncmp(tree_type, sp, 4) && sp[4] == '}') + else if (!prefixcmp(sp, "tree}")) expected_type = OBJ_TREE; - else if (!strncmp(blob_type, sp, 4) && sp[4] == '}') + else if (!prefixcmp(sp, "blob}")) expected_type = OBJ_BLOB; else if (!prefixcmp(sp, "object}")) expected_type = OBJ_ANY; -- cgit v1.2.1