[PATCH] sha1_name: do not accept .git/refs/snap/.
commit1dfcfbce2d643b7c7b56dc828f36ced9de2bf9f2
authorJunio C Hamano <junkio@cox.net>
Sun, 21 Aug 2005 09:43:08 +0000 (21 02:43 -0700)
committerJunio C Hamano <junkio@cox.net>
Sun, 21 Aug 2005 10:52:55 +0000 (21 03:52 -0700)
treedd246bc26ac7a2bc5ae5cee885dc29651f8ca44d
parent90a734dc7f37a7bd1f3beec4d33acad559360f6c
[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;
sha1_name.c