1/*2* rev-parse.c3*4* Copyright (C) Linus Torvalds, 20055*/6#include "cache.h"7#include "commit.h"8#include "refs.h"910#define DO_REVS 111#define DO_NOREV 212#define DO_FLAGS 413#define DO_NONFLAGS 814static int filter = ~0;1516static char *def = NULL;1718#define NORMAL 019#define REVERSED 120static int show_type = NORMAL;21static int symbolic = 0;22static int output_sq = 0;2324static int revs_count = 0;2526/*27* Some arguments are relevant "revision" arguments,28* others are about output format or other details.29* This sorts it all out.30*/31static int is_rev_argument(const char *arg)32{33static const char *rev_args[] = {34"--bisect",35"--header",36"--max-age=",37"--max-count=",38"--merge-order",39"--min-age=",40"--no-merges",41"--objects",42"--parents",43"--pretty",44"--show-breaks",45"--topo-order",46"--unpacked",47NULL48};49const char **p = rev_args;5051for (;;) {52const char *str = *p++;53int len;54if (!str)55return 0;56len = strlen(str);57if (!strcmp(arg, str) ||58(str[len-1] == '=' && !strncmp(arg, str, len)))59return 1;60}61}6263/* Output argument as a string, either SQ or normal */64static void show(const char *arg)65{66if (output_sq) {67int sq = '\'', ch;6869putchar(sq);70while ((ch = *arg++)) {71if (ch == sq)72fputs("'\\'", stdout);73putchar(ch);74}75putchar(sq);76putchar(' ');77}78else79puts(arg);80}8182/* Output a revision, only if filter allows it */83static void show_rev(int type, const unsigned char *sha1, const char *name)84{85if (!(filter & DO_REVS))86return;87def = NULL;88revs_count++;8990if (type != show_type)91putchar('^');92if (symbolic && name)93show(name);94else95show(sha1_to_hex(sha1));96}9798/* Output a flag, only if filter allows it. */99static void show_flag(char *arg)100{101if (!(filter & DO_FLAGS))102return;103if (filter & (is_rev_argument(arg) ? DO_REVS : DO_NOREV))104show(arg);105}106107static void show_default(void)108{109char *s = def;110111if (s) {112unsigned char sha1[20];113114def = NULL;115if (!get_sha1(s, sha1)) {116show_rev(NORMAL, sha1, s);117return;118}119}120}121122static int show_reference(const char *refname, const unsigned char *sha1)123{124show_rev(NORMAL, sha1, refname);125return 0;126}127128int main(int argc, char **argv)129{130int i, as_is = 0, verify = 0;131unsigned char sha1[20];132const char *prefix = setup_git_directory();133134for (i = 1; i < argc; i++) {135char *arg = argv[i];136char *dotdot;137138if (as_is) {139show(arg);140continue;141}142if (*arg == '-') {143if (!strcmp(arg, "--")) {144as_is = 1;145continue;146}147if (!strcmp(arg, "--default")) {148def = argv[i+1];149i++;150continue;151}152if (!strcmp(arg, "--revs-only")) {153filter &= ~DO_NOREV;154continue;155}156if (!strcmp(arg, "--no-revs")) {157filter &= ~DO_REVS;158continue;159}160if (!strcmp(arg, "--flags")) {161filter &= ~DO_NONFLAGS;162continue;163}164if (!strcmp(arg, "--no-flags")) {165filter &= ~DO_FLAGS;166continue;167}168if (!strcmp(arg, "--verify")) {169filter &= ~(DO_FLAGS|DO_NOREV);170verify = 1;171continue;172}173if (!strcmp(arg, "--sq")) {174output_sq = 1;175continue;176}177if (!strcmp(arg, "--not")) {178show_type ^= REVERSED;179continue;180}181if (!strcmp(arg, "--symbolic")) {182symbolic = 1;183continue;184}185if (!strcmp(arg, "--all")) {186for_each_ref(show_reference);187continue;188}189if (!strcmp(arg, "--show-prefix")) {190if (prefix)191puts(prefix);192continue;193}194if (verify)195die("Needed a single revision");196show_flag(arg);197continue;198}199200/* Not a flag argument */201dotdot = strstr(arg, "..");202if (dotdot) {203unsigned char end[20];204char *n = dotdot+2;205*dotdot = 0;206if (!get_sha1(arg, sha1)) {207if (!*n)208n = "HEAD";209if (!get_sha1(n, end)) {210show_rev(NORMAL, end, n);211show_rev(REVERSED, sha1, arg);212continue;213}214}215*dotdot = '.';216}217if (!get_sha1(arg, sha1)) {218show_rev(NORMAL, sha1, arg);219continue;220}221if (*arg == '^' && !get_sha1(arg+1, sha1)) {222show_rev(REVERSED, sha1, arg+1);223continue;224}225if (verify)226die("Needed a single revision");227if ((filter & (DO_NONFLAGS|DO_NOREV)) ==228(DO_NONFLAGS|DO_NOREV))229show(arg);230}231show_default();232if (verify && revs_count != 1)233die("Needed a single revision");234return 0;235}