X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=rev-parse.c;h=40707ac6ca7258878b47ed72074b3cf7364d3a56;hb=180926636e47ecfe28d03cec493af75899994f0f;hp=fd5f2ddca36ea45cd9feaf706a53aa66956db233;hpb=921d865ea24ffea6452f9b24302e651a347d7905;p=git.git diff --git a/rev-parse.c b/rev-parse.c index fd5f2ddc..40707ac6 100644 --- a/rev-parse.c +++ b/rev-parse.c @@ -4,6 +4,9 @@ * Copyright (C) Linus Torvalds, 2005 */ #include "cache.h" +#include "commit.h" + +static int get_extended_sha1(char *name, unsigned char *sha1); /* * Some arguments are relevant "revision" arguments, @@ -32,6 +35,56 @@ static int is_rev_argument(const char *arg) } } +static int get_parent(char *name, unsigned char *result, int idx) +{ + unsigned char sha1[20]; + int ret = get_extended_sha1(name, sha1); + struct commit *commit; + struct commit_list *p; + + if (ret) + return ret; + commit = lookup_commit_reference(sha1); + if (!commit) + return -1; + if (parse_commit(commit)) + return -1; + p = commit->parents; + while (p) { + if (!--idx) { + memcpy(result, p->item->object.sha1, 20); + return 0; + } + p = p->next; + } + return -1; +} + +/* + * This is like "get_sha1()", except it allows "sha1 expressions", + * notably "xyz^" for "parent of xyz" + */ +static int get_extended_sha1(char *name, unsigned char *sha1) +{ + int parent; + int len = strlen(name); + + parent = 1; + if (len > 2 && name[len-1] >= '1' && name[len-1] <= '9') { + parent = name[len-1] - '0'; + len--; + } + if (len > 1 && name[len-1] == '^') { + int ret; + name[len-1] = 0; + ret = get_parent(name, sha1, parent); + name[len-1] = '^'; + if (!ret) + return 0; + } + return get_sha1(name, sha1); +} + int main(int argc, char **argv) { int i, as_is = 0, revs_only = 0, no_revs = 0; @@ -78,29 +131,15 @@ int main(int argc, char **argv) printf("%s\n", arg); continue; } - if (!get_sha1(arg, sha1)) { - if (no_revs) - continue; - def = NULL; - printf("%s\n", sha1_to_hex(sha1)); - continue; - } - if (*arg == '^' && !get_sha1(arg+1, sha1)) { - if (no_revs) - continue; - def = NULL; - printf("^%s\n", sha1_to_hex(sha1)); - continue; - } dotdot = strstr(arg, ".."); if (dotdot) { unsigned char end[20]; char *n = dotdot+2; *dotdot = 0; - if (!get_sha1(arg, sha1)) { + if (!get_extended_sha1(arg, sha1)) { if (!*n) n = "HEAD"; - if (!get_sha1(n, end)) { + if (!get_extended_sha1(n, end)) { if (no_revs) continue; def = NULL; @@ -111,9 +150,26 @@ int main(int argc, char **argv) } *dotdot = '.'; } + if (!get_extended_sha1(arg, sha1)) { + if (no_revs) + continue; + def = NULL; + printf("%s\n", sha1_to_hex(sha1)); + continue; + } + if (*arg == '^' && !get_extended_sha1(arg+1, sha1)) { + if (no_revs) + continue; + def = NULL; + printf("^%s\n", sha1_to_hex(sha1)); + continue; + } + if (def) { + printf("%s\n", def); + def = NULL; + } if (revs_only) continue; - def = NULL; printf("%s\n", arg); } if (def)