From: Linus Torvalds Date: Mon, 2 May 2005 01:13:16 +0000 (-0700) Subject: Add "look up parent" logic for the simple names. X-Git-Tag: v0.99~670 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=35ad33823e90fb166a6480cdc9195051535e9788;p=git.git Add "look up parent" logic for the simple names. It uses the jit syntax, at least for now. 0-xxxx is the first parent of xxxx, while 1-xxxx is the second, and so on. You can use just "-xxxx" for the first parent, but a lot of commands will think that the initial '-' implies a command line flag. --- diff --git a/sha1_file.c b/sha1_file.c index d91e072f3..e1ee0ad34 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -60,17 +60,74 @@ int get_sha1_file(const char *path, unsigned char *result) return get_sha1_hex(buffer, result); } +static int get_parent(int index, const char *str, unsigned char *result) +{ + unsigned char sha1[20]; + char *buffer; + unsigned long size, offset; + int ret; + + if (get_sha1(str, sha1) < 0) + return -1; + buffer = read_object_with_reference(sha1, "commit", &size, NULL); + if (!buffer) + return -1; + ret = -1; + offset = 46; + for (;;) { + if (offset + 48 > size) + break; + if (memcmp(buffer + offset, "parent ", 7)) + break; + if (index > 0) { + offset += 48; + index--; + continue; + } + ret = get_sha1_hex(buffer + offset + 7, result); + break; + } + free(buffer); + return ret; +} + int get_sha1(const char *str, unsigned char *sha1) { static char pathname[PATH_MAX]; + static const char *prefix[] = { + "", + "refs", + "refs/tags", + "refs/heads", + "refs/snap", + NULL + }; + const char *gitdir; + const char **p; if (!get_sha1_hex(str, sha1)) return 0; - if (!get_sha1_file(str, sha1)) - return 0; - snprintf(pathname, sizeof(pathname), ".git/%s", str); - if (!get_sha1_file(pathname, sha1)) - return 0; + + switch (*str) { + case '/': + if (!get_sha1_file(str, sha1)) + return 0; + break; + case '-': + return get_parent(0, str+1, sha1); + case '0' ... '9': + if (str[1] == '-') + return get_parent(*str - '0', str+2, sha1); + break; + } + + gitdir = ".git"; + for (p = prefix; *p; p++) { + snprintf(pathname, sizeof(pathname), "%s/%s/%s", gitdir, *p, str); + if (!get_sha1_file(pathname, sha1)) + return 0; + } + return -1; }