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.
This commit is contained in:
parent
3c249c9506
commit
35ad33823e
67
sha1_file.c
67
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user