summaryrefslogtreecommitdiff
path: root/sha1_name.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2005-08-21 09:43:08 (GMT)
committerJunio C Hamano <junkio@cox.net>2005-08-21 10:52:55 (GMT)
commit1dfcfbce2d643b7c7b56dc828f36ced9de2bf9f2 (patch)
treedd246bc26ac7a2bc5ae5cee885dc29651f8ca44d /sha1_name.c
parent90a734dc7f37a7bd1f3beec4d33acad559360f6c (diff)
downloadgit-1dfcfbce2d643b7c7b56dc828f36ced9de2bf9f2.zip
git-1dfcfbce2d643b7c7b56dc828f36ced9de2bf9f2.tar.gz
git-1dfcfbce2d643b7c7b56dc828f36ced9de2bf9f2.tar.bz2
[PATCH] sha1_name: do not accept .git/refs/snap/.
I think Linus did a cut & paste from an early JIT code while developing the current extended SHA1 notation, and left it there as a courtesy, but the directory does not deserve to be treated any more specially than, say, .git/refs/bisect. If the subdirectories under .git/refs proliferate, we may want to switch to scanning that hierarchy at runtime, instead of the current hard-coded set, although I think that would be overkill. Signed-off-by: Junio C Hamano <junkio@cox.net> From nobody Mon Sep 17 00:00:00 2001 Subject: [PATCH] Add a new extended SHA1 syntax <name>:<num> From: Junio C Hamano <junkio@cox.net> Date: 1124617434 -0700 The new notation is a short-hand for <name> followed by <num> caret ('^') characters. E.g. "master:4" is the fourth generation ancestor of the current "master" branch head, following the first parents; same as "master^^^^" but a bit more readable. This will be used in the updated "git show-branch" command. Signed-off-by: Junio C Hamano <junkio@cox.net> --- sha1_name.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 41 insertions(+), 0 deletions(-) d5098ce769da46df6d45dc8f41b06dd758fdaea7 diff --git a/sha1_name.c b/sha1_name.c --- a/sha1_name.c +++ b/sha1_name.c @@ -191,9 +191,29 @@ static int get_parent(const char *name, return -1; } +static int get_nth_ancestor(const char *name, int len, + unsigned char *result, int generation) +{ + unsigned char sha1[20]; + int ret = get_sha1_1(name, len, sha1); + if (ret) + return ret; + + while (generation--) { + struct commit *commit = lookup_commit_reference(sha1); + + if (!commit || parse_commit(commit) || !commit->parents) + return -1; + memcpy(sha1, commit->parents->item->object.sha1, 20); + } + memcpy(result, sha1, 20); + return 0; +} + static int get_sha1_1(const char *name, int len, unsigned char *sha1) { int parent, ret; + const char *cp; /* foo^[0-9] or foo^ (== foo^1); we do not do more than 9 parents. */ if (len > 2 && name[len-2] == '^' && @@ -210,6 +230,27 @@ static int get_sha1_1(const char *name, if (parent >= 0) return get_parent(name, len, sha1, parent); + /* name:3 is name^^^, + * name:12 is name^^^^^^^^^^^^, and + * name: is name + */ + parent = 0; + for (cp = name + len - 1; name <= cp; cp--) { + int ch = *cp; + if ('0' <= ch && ch <= '9') + continue; + if (ch != ':') + parent = -1; + break; + } + if (!parent && *cp == ':') { + int len1 = cp - name; + cp++; + while (cp < name + len) + parent = parent * 10 + *cp++ - '0'; + return get_nth_ancestor(name, len1, sha1, parent); + } + ret = get_sha1_basic(name, len, sha1); if (!ret) return 0;
Diffstat (limited to 'sha1_name.c')
-rw-r--r--sha1_name.c1
1 files changed, 0 insertions, 1 deletions
diff --git a/sha1_name.c b/sha1_name.c
index fdd3214..6744bbb 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -143,7 +143,6 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
"refs",
"refs/tags",
"refs/heads",
- "refs/snap",
NULL
};
const char **p;