1 /*
2  * rev-parse.c
3  *
4  * Copyright (C) Linus Torvalds, 2005
5  */
6 #define USE_THE_INDEX_COMPATIBILITY_MACROS
7 #include "cache.h"
8 #include "config.h"
9 #include "commit.h"
10 #include "refs.h"
11 #include "quote.h"
12 #include "builtin.h"
13 #include "parse-options.h"
14 #include "diff.h"
15 #include "revision.h"
16 #include "split-index.h"
17 #include "submodule.h"
18 #include "commit-reach.h"
19 #include "shallow.h"
20 
21 #define DO_REVS		1
22 #define DO_NOREV	2
23 #define DO_FLAGS	4
24 #define DO_NONFLAGS	8
25 static int filter = ~0;
26 
27 static const char *def;
28 
29 #define NORMAL 0
30 #define REVERSED 1
31 static int show_type = NORMAL;
32 
33 #define SHOW_SYMBOLIC_ASIS 1
34 #define SHOW_SYMBOLIC_FULL 2
35 static int symbolic;
36 static int abbrev;
37 static int abbrev_ref;
38 static int abbrev_ref_strict;
39 static int output_sq;
40 
41 static int stuck_long;
42 static struct string_list *ref_excludes;
43 
44 /*
45  * Some arguments are relevant "revision" arguments,
46  * others are about output format or other details.
47  * This sorts it all out.
48  */
is_rev_argument(const char * arg)49 static int is_rev_argument(const char *arg)
50 {
51 	static const char *rev_args[] = {
52 		"--all",
53 		"--bisect",
54 		"--dense",
55 		"--branches=",
56 		"--branches",
57 		"--header",
58 		"--ignore-missing",
59 		"--max-age=",
60 		"--max-count=",
61 		"--min-age=",
62 		"--no-merges",
63 		"--min-parents=",
64 		"--no-min-parents",
65 		"--max-parents=",
66 		"--no-max-parents",
67 		"--objects",
68 		"--objects-edge",
69 		"--parents",
70 		"--pretty",
71 		"--remotes=",
72 		"--remotes",
73 		"--glob=",
74 		"--sparse",
75 		"--tags=",
76 		"--tags",
77 		"--topo-order",
78 		"--date-order",
79 		"--unpacked",
80 		NULL
81 	};
82 	const char **p = rev_args;
83 
84 	/* accept -<digit>, like traditional "head" */
85 	if ((*arg == '-') && isdigit(arg[1]))
86 		return 1;
87 
88 	for (;;) {
89 		const char *str = *p++;
90 		int len;
91 		if (!str)
92 			return 0;
93 		len = strlen(str);
94 		if (!strcmp(arg, str) ||
95 		    (str[len-1] == '=' && !strncmp(arg, str, len)))
96 			return 1;
97 	}
98 }
99 
100 /* Output argument as a string, either SQ or normal */
show(const char * arg)101 static void show(const char *arg)
102 {
103 	if (output_sq) {
104 		int sq = '\'', ch;
105 
106 		putchar(sq);
107 		while ((ch = *arg++)) {
108 			if (ch == sq)
109 				fputs("'\\'", stdout);
110 			putchar(ch);
111 		}
112 		putchar(sq);
113 		putchar(' ');
114 	}
115 	else
116 		puts(arg);
117 }
118 
119 /* Like show(), but with a negation prefix according to type */
show_with_type(int type,const char * arg)120 static void show_with_type(int type, const char *arg)
121 {
122 	if (type != show_type)
123 		putchar('^');
124 	show(arg);
125 }
126 
127 /* Output a revision, only if filter allows it */
show_rev(int type,const struct object_id * oid,const char * name)128 static void show_rev(int type, const struct object_id *oid, const char *name)
129 {
130 	if (!(filter & DO_REVS))
131 		return;
132 	def = NULL;
133 
134 	if ((symbolic || abbrev_ref) && name) {
135 		if (symbolic == SHOW_SYMBOLIC_FULL || abbrev_ref) {
136 			struct object_id discard;
137 			char *full;
138 
139 			switch (dwim_ref(name, strlen(name), &discard, &full, 0)) {
140 			case 0:
141 				/*
142 				 * Not found -- not a ref.  We could
143 				 * emit "name" here, but symbolic-full
144 				 * users are interested in finding the
145 				 * refs spelled in full, and they would
146 				 * need to filter non-refs if we did so.
147 				 */
148 				break;
149 			case 1: /* happy */
150 				if (abbrev_ref)
151 					full = shorten_unambiguous_ref(full,
152 						abbrev_ref_strict);
153 				show_with_type(type, full);
154 				break;
155 			default: /* ambiguous */
156 				error("refname '%s' is ambiguous", name);
157 				break;
158 			}
159 			free(full);
160 		} else {
161 			show_with_type(type, name);
162 		}
163 	}
164 	else if (abbrev)
165 		show_with_type(type, find_unique_abbrev(oid, abbrev));
166 	else
167 		show_with_type(type, oid_to_hex(oid));
168 }
169 
170 /* Output a flag, only if filter allows it. */
show_flag(const char * arg)171 static int show_flag(const char *arg)
172 {
173 	if (!(filter & DO_FLAGS))
174 		return 0;
175 	if (filter & (is_rev_argument(arg) ? DO_REVS : DO_NOREV)) {
176 		show(arg);
177 		return 1;
178 	}
179 	return 0;
180 }
181 
show_default(void)182 static int show_default(void)
183 {
184 	const char *s = def;
185 
186 	if (s) {
187 		struct object_id oid;
188 
189 		def = NULL;
190 		if (!get_oid(s, &oid)) {
191 			show_rev(NORMAL, &oid, s);
192 			return 1;
193 		}
194 	}
195 	return 0;
196 }
197 
show_reference(const char * refname,const struct object_id * oid,int flag,void * cb_data)198 static int show_reference(const char *refname, const struct object_id *oid, int flag, void *cb_data)
199 {
200 	if (ref_excluded(ref_excludes, refname))
201 		return 0;
202 	show_rev(NORMAL, oid, refname);
203 	return 0;
204 }
205 
anti_reference(const char * refname,const struct object_id * oid,int flag,void * cb_data)206 static int anti_reference(const char *refname, const struct object_id *oid, int flag, void *cb_data)
207 {
208 	show_rev(REVERSED, oid, refname);
209 	return 0;
210 }
211 
show_abbrev(const struct object_id * oid,void * cb_data)212 static int show_abbrev(const struct object_id *oid, void *cb_data)
213 {
214 	show_rev(NORMAL, oid, NULL);
215 	return 0;
216 }
217 
show_datestring(const char * flag,const char * datestr)218 static void show_datestring(const char *flag, const char *datestr)
219 {
220 	char *buffer;
221 
222 	/* date handling requires both flags and revs */
223 	if ((filter & (DO_FLAGS | DO_REVS)) != (DO_FLAGS | DO_REVS))
224 		return;
225 	buffer = xstrfmt("%s%"PRItime, flag, approxidate(datestr));
226 	show(buffer);
227 	free(buffer);
228 }
229 
show_file(const char * arg,int output_prefix)230 static int show_file(const char *arg, int output_prefix)
231 {
232 	show_default();
233 	if ((filter & (DO_NONFLAGS|DO_NOREV)) == (DO_NONFLAGS|DO_NOREV)) {
234 		if (output_prefix) {
235 			const char *prefix = startup_info->prefix;
236 			char *fname = prefix_filename(prefix, arg);
237 			show(fname);
238 			free(fname);
239 		} else
240 			show(arg);
241 		return 1;
242 	}
243 	return 0;
244 }
245 
try_difference(const char * arg)246 static int try_difference(const char *arg)
247 {
248 	char *dotdot;
249 	struct object_id start_oid;
250 	struct object_id end_oid;
251 	const char *end;
252 	const char *start;
253 	int symmetric;
254 	static const char head_by_default[] = "HEAD";
255 
256 	if (!(dotdot = strstr(arg, "..")))
257 		return 0;
258 	end = dotdot + 2;
259 	start = arg;
260 	symmetric = (*end == '.');
261 
262 	*dotdot = 0;
263 	end += symmetric;
264 
265 	if (!*end)
266 		end = head_by_default;
267 	if (dotdot == arg)
268 		start = head_by_default;
269 
270 	if (start == head_by_default && end == head_by_default &&
271 	    !symmetric) {
272 		/*
273 		 * Just ".."?  That is not a range but the
274 		 * pathspec for the parent directory.
275 		 */
276 		*dotdot = '.';
277 		return 0;
278 	}
279 
280 	if (!get_oid_committish(start, &start_oid) && !get_oid_committish(end, &end_oid)) {
281 		show_rev(NORMAL, &end_oid, end);
282 		show_rev(symmetric ? NORMAL : REVERSED, &start_oid, start);
283 		if (symmetric) {
284 			struct commit_list *exclude;
285 			struct commit *a, *b;
286 			a = lookup_commit_reference(the_repository, &start_oid);
287 			b = lookup_commit_reference(the_repository, &end_oid);
288 			if (!a || !b) {
289 				*dotdot = '.';
290 				return 0;
291 			}
292 			exclude = get_merge_bases(a, b);
293 			while (exclude) {
294 				struct commit *commit = pop_commit(&exclude);
295 				show_rev(REVERSED, &commit->object.oid, NULL);
296 			}
297 		}
298 		*dotdot = '.';
299 		return 1;
300 	}
301 	*dotdot = '.';
302 	return 0;
303 }
304 
try_parent_shorthands(const char * arg)305 static int try_parent_shorthands(const char *arg)
306 {
307 	char *dotdot;
308 	struct object_id oid;
309 	struct commit *commit;
310 	struct commit_list *parents;
311 	int parent_number;
312 	int include_rev = 0;
313 	int include_parents = 0;
314 	int exclude_parent = 0;
315 
316 	if ((dotdot = strstr(arg, "^!"))) {
317 		include_rev = 1;
318 		if (dotdot[2])
319 			return 0;
320 	} else if ((dotdot = strstr(arg, "^@"))) {
321 		include_parents = 1;
322 		if (dotdot[2])
323 			return 0;
324 	} else if ((dotdot = strstr(arg, "^-"))) {
325 		include_rev = 1;
326 		exclude_parent = 1;
327 
328 		if (dotdot[2]) {
329 			char *end;
330 			exclude_parent = strtoul(dotdot + 2, &end, 10);
331 			if (*end != '\0' || !exclude_parent)
332 				return 0;
333 		}
334 	} else
335 		return 0;
336 
337 	*dotdot = 0;
338 	if (get_oid_committish(arg, &oid) ||
339 	    !(commit = lookup_commit_reference(the_repository, &oid))) {
340 		*dotdot = '^';
341 		return 0;
342 	}
343 
344 	if (exclude_parent &&
345 	    exclude_parent > commit_list_count(commit->parents)) {
346 		*dotdot = '^';
347 		return 0;
348 	}
349 
350 	if (include_rev)
351 		show_rev(NORMAL, &oid, arg);
352 	for (parents = commit->parents, parent_number = 1;
353 	     parents;
354 	     parents = parents->next, parent_number++) {
355 		char *name = NULL;
356 
357 		if (exclude_parent && parent_number != exclude_parent)
358 			continue;
359 
360 		if (symbolic)
361 			name = xstrfmt("%s^%d", arg, parent_number);
362 		show_rev(include_parents ? NORMAL : REVERSED,
363 			 &parents->item->object.oid, name);
364 		free(name);
365 	}
366 
367 	*dotdot = '^';
368 	return 1;
369 }
370 
parseopt_dump(const struct option * o,const char * arg,int unset)371 static int parseopt_dump(const struct option *o, const char *arg, int unset)
372 {
373 	struct strbuf *parsed = o->value;
374 	if (unset)
375 		strbuf_addf(parsed, " --no-%s", o->long_name);
376 	else if (o->short_name && (o->long_name == NULL || !stuck_long))
377 		strbuf_addf(parsed, " -%c", o->short_name);
378 	else
379 		strbuf_addf(parsed, " --%s", o->long_name);
380 	if (arg) {
381 		if (!stuck_long)
382 			strbuf_addch(parsed, ' ');
383 		else if (o->long_name)
384 			strbuf_addch(parsed, '=');
385 		sq_quote_buf(parsed, arg);
386 	}
387 	return 0;
388 }
389 
skipspaces(const char * s)390 static const char *skipspaces(const char *s)
391 {
392 	while (isspace(*s))
393 		s++;
394 	return s;
395 }
396 
findspace(const char * s)397 static char *findspace(const char *s)
398 {
399 	for (; *s; s++)
400 		if (isspace(*s))
401 			return (char*)s;
402 	return NULL;
403 }
404 
cmd_parseopt(int argc,const char ** argv,const char * prefix)405 static int cmd_parseopt(int argc, const char **argv, const char *prefix)
406 {
407 	static int keep_dashdash = 0, stop_at_non_option = 0;
408 	static char const * const parseopt_usage[] = {
409 		N_("git rev-parse --parseopt [<options>] -- [<args>...]"),
410 		NULL
411 	};
412 	static struct option parseopt_opts[] = {
413 		OPT_BOOL(0, "keep-dashdash", &keep_dashdash,
414 					N_("keep the `--` passed as an arg")),
415 		OPT_BOOL(0, "stop-at-non-option", &stop_at_non_option,
416 					N_("stop parsing after the "
417 					   "first non-option argument")),
418 		OPT_BOOL(0, "stuck-long", &stuck_long,
419 					N_("output in stuck long form")),
420 		OPT_END(),
421 	};
422 	static const char * const flag_chars = "*=?!";
423 
424 	struct strbuf sb = STRBUF_INIT, parsed = STRBUF_INIT;
425 	const char **usage = NULL;
426 	struct option *opts = NULL;
427 	int onb = 0, osz = 0, unb = 0, usz = 0;
428 
429 	strbuf_addstr(&parsed, "set --");
430 	argc = parse_options(argc, argv, prefix, parseopt_opts, parseopt_usage,
431 	                     PARSE_OPT_KEEP_DASHDASH);
432 	if (argc < 1 || strcmp(argv[0], "--"))
433 		usage_with_options(parseopt_usage, parseopt_opts);
434 
435 	/* get the usage up to the first line with a -- on it */
436 	for (;;) {
437 		if (strbuf_getline(&sb, stdin) == EOF)
438 			die(_("premature end of input"));
439 		ALLOC_GROW(usage, unb + 1, usz);
440 		if (!strcmp("--", sb.buf)) {
441 			if (unb < 1)
442 				die(_("no usage string given before the `--' separator"));
443 			usage[unb] = NULL;
444 			break;
445 		}
446 		usage[unb++] = strbuf_detach(&sb, NULL);
447 	}
448 
449 	/* parse: (<short>|<short>,<long>|<long>)[*=?!]*<arghint>? SP+ <help> */
450 	while (strbuf_getline(&sb, stdin) != EOF) {
451 		const char *s;
452 		char *help;
453 		struct option *o;
454 
455 		if (!sb.len)
456 			continue;
457 
458 		ALLOC_GROW(opts, onb + 1, osz);
459 		memset(opts + onb, 0, sizeof(opts[onb]));
460 
461 		o = &opts[onb++];
462 		help = findspace(sb.buf);
463 		if (!help || sb.buf == help) {
464 			o->type = OPTION_GROUP;
465 			o->help = xstrdup(skipspaces(sb.buf));
466 			continue;
467 		}
468 
469 		*help = '\0';
470 
471 		o->type = OPTION_CALLBACK;
472 		o->help = xstrdup(skipspaces(help+1));
473 		o->value = &parsed;
474 		o->flags = PARSE_OPT_NOARG;
475 		o->callback = &parseopt_dump;
476 
477 		/* name(s) */
478 		s = strpbrk(sb.buf, flag_chars);
479 		if (s == NULL)
480 			s = help;
481 
482 		if (s - sb.buf == 1) /* short option only */
483 			o->short_name = *sb.buf;
484 		else if (sb.buf[1] != ',') /* long option only */
485 			o->long_name = xmemdupz(sb.buf, s - sb.buf);
486 		else {
487 			o->short_name = *sb.buf;
488 			o->long_name = xmemdupz(sb.buf + 2, s - sb.buf - 2);
489 		}
490 
491 		/* flags */
492 		while (s < help) {
493 			switch (*s++) {
494 			case '=':
495 				o->flags &= ~PARSE_OPT_NOARG;
496 				continue;
497 			case '?':
498 				o->flags &= ~PARSE_OPT_NOARG;
499 				o->flags |= PARSE_OPT_OPTARG;
500 				continue;
501 			case '!':
502 				o->flags |= PARSE_OPT_NONEG;
503 				continue;
504 			case '*':
505 				o->flags |= PARSE_OPT_HIDDEN;
506 				continue;
507 			}
508 			s--;
509 			break;
510 		}
511 
512 		if (s < help)
513 			o->argh = xmemdupz(s, help - s);
514 	}
515 	strbuf_release(&sb);
516 
517 	/* put an OPT_END() */
518 	ALLOC_GROW(opts, onb + 1, osz);
519 	memset(opts + onb, 0, sizeof(opts[onb]));
520 	argc = parse_options(argc, argv, prefix, opts, usage,
521 			(keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0) |
522 			(stop_at_non_option ? PARSE_OPT_STOP_AT_NON_OPTION : 0) |
523 			PARSE_OPT_SHELL_EVAL);
524 
525 	strbuf_addstr(&parsed, " --");
526 	sq_quote_argv(&parsed, argv);
527 	puts(parsed.buf);
528 	return 0;
529 }
530 
cmd_sq_quote(int argc,const char ** argv)531 static int cmd_sq_quote(int argc, const char **argv)
532 {
533 	struct strbuf buf = STRBUF_INIT;
534 
535 	if (argc)
536 		sq_quote_argv(&buf, argv);
537 	printf("%s\n", buf.buf);
538 	strbuf_release(&buf);
539 
540 	return 0;
541 }
542 
die_no_single_rev(int quiet)543 static void die_no_single_rev(int quiet)
544 {
545 	if (quiet)
546 		exit(1);
547 	else
548 		die(_("Needed a single revision"));
549 }
550 
551 static const char builtin_rev_parse_usage[] =
552 N_("git rev-parse --parseopt [<options>] -- [<args>...]\n"
553    "   or: git rev-parse --sq-quote [<arg>...]\n"
554    "   or: git rev-parse [<options>] [<arg>...]\n"
555    "\n"
556    "Run \"git rev-parse --parseopt -h\" for more information on the first usage.");
557 
558 /*
559  * Parse "opt" or "opt=<value>", setting value respectively to either
560  * NULL or the string after "=".
561  */
opt_with_value(const char * arg,const char * opt,const char ** value)562 static int opt_with_value(const char *arg, const char *opt, const char **value)
563 {
564 	if (skip_prefix(arg, opt, &arg)) {
565 		if (!*arg) {
566 			*value = NULL;
567 			return 1;
568 		}
569 		if (*arg++ == '=') {
570 			*value = arg;
571 			return 1;
572 		}
573 	}
574 	return 0;
575 }
576 
handle_ref_opt(const char * pattern,const char * prefix)577 static void handle_ref_opt(const char *pattern, const char *prefix)
578 {
579 	if (pattern)
580 		for_each_glob_ref_in(show_reference, pattern, prefix, NULL);
581 	else
582 		for_each_ref_in(prefix, show_reference, NULL);
583 	clear_ref_exclusion(&ref_excludes);
584 }
585 
586 enum format_type {
587 	/* We would like a relative path. */
588 	FORMAT_RELATIVE,
589 	/* We would like a canonical absolute path. */
590 	FORMAT_CANONICAL,
591 	/* We would like the default behavior. */
592 	FORMAT_DEFAULT,
593 };
594 
595 enum default_type {
596 	/* Our default is a relative path. */
597 	DEFAULT_RELATIVE,
598 	/* Our default is a relative path if there's a shared root. */
599 	DEFAULT_RELATIVE_IF_SHARED,
600 	/* Our default is a canonical absolute path. */
601 	DEFAULT_CANONICAL,
602 	/* Our default is not to modify the item. */
603 	DEFAULT_UNMODIFIED,
604 };
605 
print_path(const char * path,const char * prefix,enum format_type format,enum default_type def)606 static void print_path(const char *path, const char *prefix, enum format_type format, enum default_type def)
607 {
608 	char *cwd = NULL;
609 	/*
610 	 * We don't ever produce a relative path if prefix is NULL, so set the
611 	 * prefix to the current directory so that we can produce a relative
612 	 * path whenever possible.  If we're using RELATIVE_IF_SHARED mode, then
613 	 * we want an absolute path unless the two share a common prefix, so don't
614 	 * set it in that case, since doing so causes a relative path to always
615 	 * be produced if possible.
616 	 */
617 	if (!prefix && (format != FORMAT_DEFAULT || def != DEFAULT_RELATIVE_IF_SHARED))
618 		prefix = cwd = xgetcwd();
619 	if (format == FORMAT_DEFAULT && def == DEFAULT_UNMODIFIED) {
620 		puts(path);
621 	} else if (format == FORMAT_RELATIVE ||
622 		  (format == FORMAT_DEFAULT && def == DEFAULT_RELATIVE)) {
623 		/*
624 		 * In order for relative_path to work as expected, we need to
625 		 * make sure that both paths are absolute paths.  If we don't,
626 		 * we can end up with an unexpected absolute path that the user
627 		 * didn't want.
628 		 */
629 		struct strbuf buf = STRBUF_INIT, realbuf = STRBUF_INIT, prefixbuf = STRBUF_INIT;
630 		if (!is_absolute_path(path)) {
631 			strbuf_realpath_forgiving(&realbuf, path,  1);
632 			path = realbuf.buf;
633 		}
634 		if (!is_absolute_path(prefix)) {
635 			strbuf_realpath_forgiving(&prefixbuf, prefix, 1);
636 			prefix = prefixbuf.buf;
637 		}
638 		puts(relative_path(path, prefix, &buf));
639 		strbuf_release(&buf);
640 		strbuf_release(&realbuf);
641 		strbuf_release(&prefixbuf);
642 	} else if (format == FORMAT_DEFAULT && def == DEFAULT_RELATIVE_IF_SHARED) {
643 		struct strbuf buf = STRBUF_INIT;
644 		puts(relative_path(path, prefix, &buf));
645 		strbuf_release(&buf);
646 	} else {
647 		struct strbuf buf = STRBUF_INIT;
648 		strbuf_realpath_forgiving(&buf, path, 1);
649 		puts(buf.buf);
650 		strbuf_release(&buf);
651 	}
652 	free(cwd);
653 }
654 
cmd_rev_parse(int argc,const char ** argv,const char * prefix)655 int cmd_rev_parse(int argc, const char **argv, const char *prefix)
656 {
657 	int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
658 	int did_repo_setup = 0;
659 	int has_dashdash = 0;
660 	int output_prefix = 0;
661 	struct object_id oid;
662 	unsigned int flags = 0;
663 	const char *name = NULL;
664 	struct object_context unused;
665 	struct strbuf buf = STRBUF_INIT;
666 	const int hexsz = the_hash_algo->hexsz;
667 	int seen_end_of_options = 0;
668 	enum format_type format = FORMAT_DEFAULT;
669 
670 	if (argc > 1 && !strcmp("--parseopt", argv[1]))
671 		return cmd_parseopt(argc - 1, argv + 1, prefix);
672 
673 	if (argc > 1 && !strcmp("--sq-quote", argv[1]))
674 		return cmd_sq_quote(argc - 2, argv + 2);
675 
676 	if (argc > 1 && !strcmp("-h", argv[1]))
677 		usage(builtin_rev_parse_usage);
678 
679 	for (i = 1; i < argc; i++) {
680 		if (!strcmp(argv[i], "--")) {
681 			has_dashdash = 1;
682 			break;
683 		}
684 	}
685 
686 	/* No options; just report on whether we're in a git repo or not. */
687 	if (argc == 1) {
688 		setup_git_directory();
689 		git_config(git_default_config, NULL);
690 		return 0;
691 	}
692 
693 	for (i = 1; i < argc; i++) {
694 		const char *arg = argv[i];
695 
696 		if (as_is) {
697 			if (show_file(arg, output_prefix) && as_is < 2)
698 				verify_filename(prefix, arg, 0);
699 			continue;
700 		}
701 
702 		if (!seen_end_of_options) {
703 			if (!strcmp(arg, "--local-env-vars")) {
704 				int i;
705 				for (i = 0; local_repo_env[i]; i++)
706 					printf("%s\n", local_repo_env[i]);
707 				continue;
708 			}
709 			if (!strcmp(arg, "--resolve-git-dir")) {
710 				const char *gitdir = argv[++i];
711 				if (!gitdir)
712 					die(_("--resolve-git-dir requires an argument"));
713 				gitdir = resolve_gitdir(gitdir);
714 				if (!gitdir)
715 					die(_("not a gitdir '%s'"), argv[i]);
716 				puts(gitdir);
717 				continue;
718 			}
719 		}
720 
721 		/* The rest of the options require a git repository. */
722 		if (!did_repo_setup) {
723 			prefix = setup_git_directory();
724 			git_config(git_default_config, NULL);
725 			did_repo_setup = 1;
726 		}
727 
728 		if (!strcmp(arg, "--")) {
729 			as_is = 2;
730 			/* Pass on the "--" if we show anything but files.. */
731 			if (filter & (DO_FLAGS | DO_REVS))
732 				show_file(arg, 0);
733 			continue;
734 		}
735 
736 		if (!seen_end_of_options && *arg == '-') {
737 			if (!strcmp(arg, "--git-path")) {
738 				if (!argv[i + 1])
739 					die(_("--git-path requires an argument"));
740 				strbuf_reset(&buf);
741 				print_path(git_path("%s", argv[i + 1]), prefix,
742 						format,
743 						DEFAULT_RELATIVE_IF_SHARED);
744 				i++;
745 				continue;
746 			}
747 			if (!strcmp(arg,"-n")) {
748 				if (++i >= argc)
749 					die(_("-n requires an argument"));
750 				if ((filter & DO_FLAGS) && (filter & DO_REVS)) {
751 					show(arg);
752 					show(argv[i]);
753 				}
754 				continue;
755 			}
756 			if (starts_with(arg, "-n")) {
757 				if ((filter & DO_FLAGS) && (filter & DO_REVS))
758 					show(arg);
759 				continue;
760 			}
761 			if (opt_with_value(arg, "--path-format", &arg)) {
762 				if (!arg)
763 					die(_("--path-format requires an argument"));
764 				if (!strcmp(arg, "absolute")) {
765 					format = FORMAT_CANONICAL;
766 				} else if (!strcmp(arg, "relative")) {
767 					format = FORMAT_RELATIVE;
768 				} else {
769 					die(_("unknown argument to --path-format: %s"), arg);
770 				}
771 				continue;
772 			}
773 			if (!strcmp(arg, "--default")) {
774 				def = argv[++i];
775 				if (!def)
776 					die(_("--default requires an argument"));
777 				continue;
778 			}
779 			if (!strcmp(arg, "--prefix")) {
780 				prefix = argv[++i];
781 				if (!prefix)
782 					die(_("--prefix requires an argument"));
783 				startup_info->prefix = prefix;
784 				output_prefix = 1;
785 				continue;
786 			}
787 			if (!strcmp(arg, "--revs-only")) {
788 				filter &= ~DO_NOREV;
789 				continue;
790 			}
791 			if (!strcmp(arg, "--no-revs")) {
792 				filter &= ~DO_REVS;
793 				continue;
794 			}
795 			if (!strcmp(arg, "--flags")) {
796 				filter &= ~DO_NONFLAGS;
797 				continue;
798 			}
799 			if (!strcmp(arg, "--no-flags")) {
800 				filter &= ~DO_FLAGS;
801 				continue;
802 			}
803 			if (!strcmp(arg, "--verify")) {
804 				filter &= ~(DO_FLAGS|DO_NOREV);
805 				verify = 1;
806 				continue;
807 			}
808 			if (!strcmp(arg, "--quiet") || !strcmp(arg, "-q")) {
809 				quiet = 1;
810 				flags |= GET_OID_QUIETLY;
811 				continue;
812 			}
813 			if (opt_with_value(arg, "--short", &arg)) {
814 				filter &= ~(DO_FLAGS|DO_NOREV);
815 				verify = 1;
816 				abbrev = DEFAULT_ABBREV;
817 				if (!arg)
818 					continue;
819 				abbrev = strtoul(arg, NULL, 10);
820 				if (abbrev < MINIMUM_ABBREV)
821 					abbrev = MINIMUM_ABBREV;
822 				else if (hexsz <= abbrev)
823 					abbrev = hexsz;
824 				continue;
825 			}
826 			if (!strcmp(arg, "--sq")) {
827 				output_sq = 1;
828 				continue;
829 			}
830 			if (!strcmp(arg, "--not")) {
831 				show_type ^= REVERSED;
832 				continue;
833 			}
834 			if (!strcmp(arg, "--symbolic")) {
835 				symbolic = SHOW_SYMBOLIC_ASIS;
836 				continue;
837 			}
838 			if (!strcmp(arg, "--symbolic-full-name")) {
839 				symbolic = SHOW_SYMBOLIC_FULL;
840 				continue;
841 			}
842 			if (opt_with_value(arg, "--abbrev-ref", &arg)) {
843 				abbrev_ref = 1;
844 				abbrev_ref_strict = warn_ambiguous_refs;
845 				if (arg) {
846 					if (!strcmp(arg, "strict"))
847 						abbrev_ref_strict = 1;
848 					else if (!strcmp(arg, "loose"))
849 						abbrev_ref_strict = 0;
850 					else
851 						die(_("unknown mode for --abbrev-ref: %s"),
852 						    arg);
853 				}
854 				continue;
855 			}
856 			if (!strcmp(arg, "--all")) {
857 				for_each_ref(show_reference, NULL);
858 				clear_ref_exclusion(&ref_excludes);
859 				continue;
860 			}
861 			if (skip_prefix(arg, "--disambiguate=", &arg)) {
862 				for_each_abbrev(arg, show_abbrev, NULL);
863 				continue;
864 			}
865 			if (!strcmp(arg, "--bisect")) {
866 				for_each_fullref_in("refs/bisect/bad", show_reference, NULL);
867 				for_each_fullref_in("refs/bisect/good", anti_reference, NULL);
868 				continue;
869 			}
870 			if (opt_with_value(arg, "--branches", &arg)) {
871 				handle_ref_opt(arg, "refs/heads/");
872 				continue;
873 			}
874 			if (opt_with_value(arg, "--tags", &arg)) {
875 				handle_ref_opt(arg, "refs/tags/");
876 				continue;
877 			}
878 			if (skip_prefix(arg, "--glob=", &arg)) {
879 				handle_ref_opt(arg, NULL);
880 				continue;
881 			}
882 			if (opt_with_value(arg, "--remotes", &arg)) {
883 				handle_ref_opt(arg, "refs/remotes/");
884 				continue;
885 			}
886 			if (skip_prefix(arg, "--exclude=", &arg)) {
887 				add_ref_exclusion(&ref_excludes, arg);
888 				continue;
889 			}
890 			if (!strcmp(arg, "--show-toplevel")) {
891 				const char *work_tree = get_git_work_tree();
892 				if (work_tree)
893 					print_path(work_tree, prefix, format, DEFAULT_UNMODIFIED);
894 				else
895 					die(_("this operation must be run in a work tree"));
896 				continue;
897 			}
898 			if (!strcmp(arg, "--show-superproject-working-tree")) {
899 				struct strbuf superproject = STRBUF_INIT;
900 				if (get_superproject_working_tree(&superproject))
901 					print_path(superproject.buf, prefix, format, DEFAULT_UNMODIFIED);
902 				strbuf_release(&superproject);
903 				continue;
904 			}
905 			if (!strcmp(arg, "--show-prefix")) {
906 				if (prefix)
907 					puts(prefix);
908 				else
909 					putchar('\n');
910 				continue;
911 			}
912 			if (!strcmp(arg, "--show-cdup")) {
913 				const char *pfx = prefix;
914 				if (!is_inside_work_tree()) {
915 					const char *work_tree =
916 						get_git_work_tree();
917 					if (work_tree)
918 						printf("%s\n", work_tree);
919 					continue;
920 				}
921 				while (pfx) {
922 					pfx = strchr(pfx, '/');
923 					if (pfx) {
924 						pfx++;
925 						printf("../");
926 					}
927 				}
928 				putchar('\n');
929 				continue;
930 			}
931 			if (!strcmp(arg, "--git-dir") ||
932 			    !strcmp(arg, "--absolute-git-dir")) {
933 				const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
934 				char *cwd;
935 				int len;
936 				enum format_type wanted = format;
937 				if (arg[2] == 'g') {	/* --git-dir */
938 					if (gitdir) {
939 						print_path(gitdir, prefix, format, DEFAULT_UNMODIFIED);
940 						continue;
941 					}
942 					if (!prefix) {
943 						print_path(".git", prefix, format, DEFAULT_UNMODIFIED);
944 						continue;
945 					}
946 				} else {		/* --absolute-git-dir */
947 					wanted = FORMAT_CANONICAL;
948 					if (!gitdir && !prefix)
949 						gitdir = ".git";
950 					if (gitdir) {
951 						struct strbuf realpath = STRBUF_INIT;
952 						strbuf_realpath(&realpath, gitdir, 1);
953 						puts(realpath.buf);
954 						strbuf_release(&realpath);
955 						continue;
956 					}
957 				}
958 				cwd = xgetcwd();
959 				len = strlen(cwd);
960 				strbuf_reset(&buf);
961 				strbuf_addf(&buf, "%s%s.git", cwd, len && cwd[len-1] != '/' ? "/" : "");
962 				free(cwd);
963 				print_path(buf.buf, prefix, wanted, DEFAULT_CANONICAL);
964 				continue;
965 			}
966 			if (!strcmp(arg, "--git-common-dir")) {
967 				print_path(get_git_common_dir(), prefix, format, DEFAULT_RELATIVE_IF_SHARED);
968 				continue;
969 			}
970 			if (!strcmp(arg, "--is-inside-git-dir")) {
971 				printf("%s\n", is_inside_git_dir() ? "true"
972 						: "false");
973 				continue;
974 			}
975 			if (!strcmp(arg, "--is-inside-work-tree")) {
976 				printf("%s\n", is_inside_work_tree() ? "true"
977 						: "false");
978 				continue;
979 			}
980 			if (!strcmp(arg, "--is-bare-repository")) {
981 				printf("%s\n", is_bare_repository() ? "true"
982 						: "false");
983 				continue;
984 			}
985 			if (!strcmp(arg, "--is-shallow-repository")) {
986 				printf("%s\n",
987 						is_repository_shallow(the_repository) ? "true"
988 						: "false");
989 				continue;
990 			}
991 			if (!strcmp(arg, "--shared-index-path")) {
992 				if (read_cache() < 0)
993 					die(_("Could not read the index"));
994 				if (the_index.split_index) {
995 					const struct object_id *oid = &the_index.split_index->base_oid;
996 					const char *path = git_path("sharedindex.%s", oid_to_hex(oid));
997 					print_path(path, prefix, format, DEFAULT_RELATIVE);
998 				}
999 				continue;
1000 			}
1001 			if (skip_prefix(arg, "--since=", &arg)) {
1002 				show_datestring("--max-age=", arg);
1003 				continue;
1004 			}
1005 			if (skip_prefix(arg, "--after=", &arg)) {
1006 				show_datestring("--max-age=", arg);
1007 				continue;
1008 			}
1009 			if (skip_prefix(arg, "--before=", &arg)) {
1010 				show_datestring("--min-age=", arg);
1011 				continue;
1012 			}
1013 			if (skip_prefix(arg, "--until=", &arg)) {
1014 				show_datestring("--min-age=", arg);
1015 				continue;
1016 			}
1017 			if (opt_with_value(arg, "--show-object-format", &arg)) {
1018 				const char *val = arg ? arg : "storage";
1019 
1020 				if (strcmp(val, "storage") &&
1021 				    strcmp(val, "input") &&
1022 				    strcmp(val, "output"))
1023 					die(_("unknown mode for --show-object-format: %s"),
1024 					    arg);
1025 				puts(the_hash_algo->name);
1026 				continue;
1027 			}
1028 			if (!strcmp(arg, "--end-of-options")) {
1029 				seen_end_of_options = 1;
1030 				if (filter & (DO_FLAGS | DO_REVS))
1031 					show_file(arg, 0);
1032 				continue;
1033 			}
1034 			if (show_flag(arg) && verify)
1035 				die_no_single_rev(quiet);
1036 			continue;
1037 		}
1038 
1039 		/* Not a flag argument */
1040 		if (try_difference(arg))
1041 			continue;
1042 		if (try_parent_shorthands(arg))
1043 			continue;
1044 		name = arg;
1045 		type = NORMAL;
1046 		if (*arg == '^') {
1047 			name++;
1048 			type = REVERSED;
1049 		}
1050 		if (!get_oid_with_context(the_repository, name,
1051 					  flags, &oid, &unused)) {
1052 			if (verify)
1053 				revs_count++;
1054 			else
1055 				show_rev(type, &oid, name);
1056 			continue;
1057 		}
1058 		if (verify)
1059 			die_no_single_rev(quiet);
1060 		if (has_dashdash)
1061 			die(_("bad revision '%s'"), arg);
1062 		as_is = 1;
1063 		if (!show_file(arg, output_prefix))
1064 			continue;
1065 		verify_filename(prefix, arg, 1);
1066 	}
1067 	strbuf_release(&buf);
1068 	if (verify) {
1069 		if (revs_count == 1) {
1070 			show_rev(type, &oid, name);
1071 			return 0;
1072 		} else if (revs_count == 0 && show_default())
1073 			return 0;
1074 		die_no_single_rev(quiet);
1075 	} else
1076 		show_default();
1077 	return 0;
1078 }
1079