X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=rev-parse.c;h=40707ac6ca7258878b47ed72074b3cf7364d3a56;hb=180926636e47ecfe28d03cec493af75899994f0f;hp=69749f5b783bfc35c91b8aa4a98ff7adac3714c1;hpb=178cb243387a24b1dec7613c4c5e97158163ac60;p=git.git diff --git a/rev-parse.c b/rev-parse.c index 69749f5b..40707ac6 100644 --- a/rev-parse.c +++ b/rev-parse.c @@ -4,10 +4,90 @@ * 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, + * others are about output format or other details. + * This sorts it all out. + */ +static int is_rev_argument(const char *arg) +{ + static const char *rev_args[] = { + "--max-count=", + "--max-age=", + "--min-age=", + "--merge-order", + NULL + }; + const char **p = rev_args; + + for (;;) { + const char *str = *p++; + int len; + if (!str) + return 0; + len = strlen(str); + if (!strncmp(arg, str, len)) + return 1; + } +} + +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; + int i, as_is = 0, revs_only = 0, no_revs = 0; char *def = NULL; unsigned char sha1[20]; @@ -25,6 +105,8 @@ int main(int argc, char **argv) printf("%s\n", def); def = NULL; } + if (revs_only) + break; as_is = 1; } if (!strcmp(arg, "--default")) { @@ -34,27 +116,33 @@ int main(int argc, char **argv) i++; continue; } + if (!strcmp(arg, "--revs-only")) { + revs_only = 1; + continue; + } + if (!strcmp(arg, "--no-revs")) { + no_revs = 1; + continue; + } + if (revs_only | no_revs) { + if (is_rev_argument(arg) != revs_only) + continue; + } printf("%s\n", arg); continue; } - def = NULL; - if (!get_sha1(arg, sha1)) { - printf("%s\n", sha1_to_hex(sha1)); - continue; - } - if (*arg == '^' && !get_sha1(arg+1, sha1)) { - 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; printf("%s\n", sha1_to_hex(end)); printf("^%s\n", sha1_to_hex(sha1)); continue; @@ -62,6 +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; printf("%s\n", arg); } if (def)