[PATCH 5/6] gitopt: convert setup_revisions(), and diff_opt_parse()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I've added --raw to diff_opt_parse() for consistency's sake:
--patch-with-raw would otherwise be inconsistently abbreviated
to --raw if it wasn't added.

--with-r => --patch-with-raw works great

Signed-off-by: Eric Wong <normalperson@xxxxxxxx>

---

 builtin-diff.c |  109 ++++---------
 builtin-log.c  |    7 -
 commit.c       |   12 +
 diff-files.c   |   22 +--
 diff-index.c   |   19 +-
 diff-tree.c    |   21 +-
 diff.c         |  182 ++++++++++++---------
 diff.h         |    1 
 gitopt/diff.h  |   26 +++
 http-push.c    |    2 
 rev-list.c     |   34 ++--
 revision.c     |  484 +++++++++++++++++++++++++-------------------------------
 revision.h     |    6 +
 13 files changed, 437 insertions(+), 488 deletions(-)
 create mode 100644 gitopt/diff.h

28cbff1d1b543e8234acc6cada0fc889d4767a59
diff --git a/builtin-diff.c b/builtin-diff.c
index d3ac581..ff4a0ec 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -12,6 +12,7 @@ #include "diffcore.h"
 #include "revision.h"
 #include "log-tree.h"
 #include "builtin.h"
+#include "gitopt/diff.h"
 
 /* NEEDSWORK: struct object has place for name but we _do_
  * know mode when we extracted the blob out of a tree, which
@@ -29,22 +30,12 @@ static int builtin_diff_files(struct rev
 			      int argc, const char **argv)
 {
 	int silent = 0;
-	while (1 < argc) {
-		const char *arg = argv[1];
-		if (!strcmp(arg, "--base"))
-			revs->max_count = 1;
-		else if (!strcmp(arg, "--ours"))
-			revs->max_count = 2;
-		else if (!strcmp(arg, "--theirs"))
-			revs->max_count = 3;
-		else if (!strcmp(arg, "-q"))
-			silent = 1;
-		else if (!strcmp(arg, "--raw"))
-			revs->diffopt.output_format = DIFF_FORMAT_RAW;
-		else
-			usage(builtin_diff_usage);
-		argv++; argc--;
-	}
+	struct exec_args *a;
+
+	g_rev = revs;
+	a = new_exec_args(argc);
+	if (gitopt_parse_ost_split(a, a, diff_files_ost, argc, argv))
+		usage(builtin_diff_usage);
 	/*
 	 * Make sure there are NO revision (i.e. pending object) parameter,
 	 * specified rev.max_count is reasonable (0 <= n <= 3), and
@@ -107,14 +98,8 @@ static int builtin_diff_b_f(struct rev_i
 	/* Blob vs file in the working tree*/
 	struct stat st;
 
-	while (1 < argc) {
-		const char *arg = argv[1];
-		if (!strcmp(arg, "--raw"))
-			revs->diffopt.output_format = DIFF_FORMAT_RAW;
-		else
-			usage(builtin_diff_usage);
-		argv++; argc--;
-	}
+	if (argc)
+		usage(builtin_diff_usage);
 	if (lstat(path, &st))
 		die("'%s': %s", path, strerror(errno));
 	if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))
@@ -135,14 +120,9 @@ static int builtin_diff_blobs(struct rev
 	/* Blobs */
 	unsigned mode = canon_mode(S_IFREG | 0644);
 
-	while (1 < argc) {
-		const char *arg = argv[1];
-		if (!strcmp(arg, "--raw"))
-			revs->diffopt.output_format = DIFF_FORMAT_RAW;
-		else
-			usage(builtin_diff_usage);
-		argv++; argc--;
-	}
+	if (argc)
+		usage(builtin_diff_usage);
+
 	stuff_change(&revs->diffopt,
 		     mode, mode,
 		     blob[0].sha1, blob[1].sha1,
@@ -155,17 +135,13 @@ static int builtin_diff_blobs(struct rev
 static int builtin_diff_index(struct rev_info *revs,
 			      int argc, const char **argv)
 {
-	int cached = 0;
-	while (1 < argc) {
-		const char *arg = argv[1];
-		if (!strcmp(arg, "--cached"))
-			cached = 1;
-		else if (!strcmp(arg, "--raw"))
-			revs->diffopt.output_format = DIFF_FORMAT_RAW;
-		else
-			usage(builtin_diff_usage);
-		argv++; argc--;
-	}
+	struct exec_args *a;
+
+	g_rev = revs;
+	a = new_exec_args(argc);
+	if (gitopt_parse_ost_split(a, a, diff_index_ost, argc, argv))
+		usage(builtin_diff_usage);
+
 	/*
 	 * Make sure there is one revision (i.e. pending object),
 	 * and there is no revision filtering parameters.
@@ -183,14 +159,6 @@ static int builtin_diff_tree(struct rev_
 {
 	const unsigned char *(sha1[2]);
 	int swap = 1;
-	while (1 < argc) {
-		const char *arg = argv[1];
-		if (!strcmp(arg, "--raw"))
-			revs->diffopt.output_format = DIFF_FORMAT_RAW;
-		else
-			usage(builtin_diff_usage);
-		argv++; argc--;
-	}
 
 	/* We saw two trees, ent[0] and ent[1].
 	 * unless ent[0] is unintesting, they are swapped
@@ -212,14 +180,6 @@ static int builtin_diff_combined(struct 
 	const unsigned char (*parent)[20];
 	int i;
 
-	while (1 < argc) {
-		const char *arg = argv[1];
-		if (!strcmp(arg, "--raw"))
-			revs->diffopt.output_format = DIFF_FORMAT_RAW;
-		else
-			usage(builtin_diff_usage);
-		argv++; argc--;
-	}
 	if (!revs->dense_combined_merges && !revs->combine_merges)
 		revs->dense_combined_merges = revs->combine_merges = 1;
 	parent = xmalloc(ents * sizeof(*parent));
@@ -250,6 +210,7 @@ int cmd_diff(int argc, const char **argv
 	int ents = 0, blobs = 0, paths = 0;
 	const char *path = NULL;
 	struct blobinfo blob[2];
+	struct exec_args *b;
 
 	/*
 	 * We could get N tree-ish in the rev.pending_objects list.
@@ -274,23 +235,14 @@ int cmd_diff(int argc, const char **argv
 	git_config(git_diff_config);
 	init_revisions(&rev);
 	rev.diffopt.output_format = DIFF_FORMAT_PATCH;
+	cached = 0;
 
-	argc = setup_revisions(argc, argv, &rev, NULL);
+	b = setup_revisions(argc, argv, &rev, NULL, diff_index_ost);
 	/* Do we have --cached and not have a pending object, then
 	 * default to HEAD by hand.  Eek.
 	 */
-	if (!rev.pending_objects) {
-		int i;
-		for (i = 1; i < argc; i++) {
-			const char *arg = argv[i];
-			if (!strcmp(arg, "--"))
-				break;
-			else if (!strcmp(arg, "--cached")) {
-				add_head(&rev);
-				break;
-			}
-		}
-	}
+	if (!rev.pending_objects && cached)
+		add_head(&rev);
 
 	for (list = rev.pending_objects; list; list = list->next) {
 		struct object *obj = list->item;
@@ -340,17 +292,18 @@ int cmd_diff(int argc, const char **argv
 	if (!ents) {
 		switch (blobs) {
 		case 0:
-			return builtin_diff_files(&rev, argc, argv);
+			return builtin_diff_files(&rev, b->argc, b->argv);
 			break;
 		case 1:
 			if (paths != 1)
 				usage(builtin_diff_usage);
-			return builtin_diff_b_f(&rev, argc, argv, blob, path);
+			return builtin_diff_b_f(&rev, b->argc, b->argv,
+						blob, path);
 			break;
 		case 2:
 			if (paths)
 				usage(builtin_diff_usage);
-			return builtin_diff_blobs(&rev, argc, argv, blob);
+			return builtin_diff_blobs(&rev, b->argc, b->argv, blob);
 			break;
 		default:
 			usage(builtin_diff_usage);
@@ -359,10 +312,10 @@ int cmd_diff(int argc, const char **argv
 	else if (blobs)
 		usage(builtin_diff_usage);
 	else if (ents == 1)
-		return builtin_diff_index(&rev, argc, argv);
+		return builtin_diff_index(&rev, b->argc, b->argv);
 	else if (ents == 2)
-		return builtin_diff_tree(&rev, argc, argv, ent);
+		return builtin_diff_tree(&rev, b->argc, b->argv, ent);
 	else
-		return builtin_diff_combined(&rev, argc, argv, ent, ents);
+		return builtin_diff_combined(&rev, b->argc, b->argv, ent, ents);
 	usage(builtin_diff_usage);
 }
diff --git a/builtin-log.c b/builtin-log.c
index 69f2911..b004bc5 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -14,14 +14,15 @@ static int cmd_log_wc(int argc, const ch
 		      struct rev_info *rev)
 {
 	struct commit *commit;
+	struct exec_args *b;
 
 	rev->abbrev = DEFAULT_ABBREV;
 	rev->commit_format = CMIT_FMT_DEFAULT;
 	rev->verbose_header = 1;
-	argc = setup_revisions(argc, argv, rev, "HEAD");
+	b = setup_revisions(argc, argv, rev, "HEAD", NULL);
 
-	if (argc > 1)
-		die("unrecognized argument: %s", argv[1]);
+	if (b->argc)
+		die("unrecognized argument: %s", b->argv[0]);
 
 	prepare_revision_walk(rev);
 	setup_pager();
diff --git a/commit.c b/commit.c
index 2717dd8..a056b25 100644
--- a/commit.c
+++ b/commit.c
@@ -26,17 +26,17 @@ enum cmit_fmt get_commit_format(const ch
 {
 	if (!*arg)
 		return CMIT_FMT_DEFAULT;
-	if (!strcmp(arg, "=raw"))
+	if (!strcmp(arg, "raw"))
 		return CMIT_FMT_RAW;
-	if (!strcmp(arg, "=medium"))
+	if (!strcmp(arg, "medium"))
 		return CMIT_FMT_MEDIUM;
-	if (!strcmp(arg, "=short"))
+	if (!strcmp(arg, "short"))
 		return CMIT_FMT_SHORT;
-	if (!strcmp(arg, "=full"))
+	if (!strcmp(arg, "full"))
 		return CMIT_FMT_FULL;
-	if (!strcmp(arg, "=fuller"))
+	if (!strcmp(arg, "fuller"))
 		return CMIT_FMT_FULLER;
-	if (!strcmp(arg, "=oneline"))
+	if (!strcmp(arg, "oneline"))
 		return CMIT_FMT_ONELINE;
 	die("invalid --pretty format");
 }
diff --git a/diff-files.c b/diff-files.c
index b9d193d..e5b69f4 100644
--- a/diff-files.c
+++ b/diff-files.c
@@ -7,6 +7,7 @@ #include "cache.h"
 #include "diff.h"
 #include "commit.h"
 #include "revision.h"
+#include "gitopt/diff.h"
 
 static const char diff_files_usage[] =
 "git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]"
@@ -15,26 +16,17 @@ COMMON_DIFF_OPTIONS_HELP;
 int main(int argc, const char **argv)
 {
 	struct rev_info rev;
-	int silent = 0;
+	struct exec_args *b;
 
+	silent = 0;
 	git_config(git_diff_config);
 	init_revisions(&rev);
 	rev.abbrev = 0;
+	g_rev = &rev;
 
-	argc = setup_revisions(argc, argv, &rev, NULL);
-	while (1 < argc && argv[1][0] == '-') {
-		if (!strcmp(argv[1], "--base"))
-			rev.max_count = 1;
-		else if (!strcmp(argv[1], "--ours"))
-			rev.max_count = 2;
-		else if (!strcmp(argv[1], "--theirs"))
-			rev.max_count = 3;
-		else if (!strcmp(argv[1], "-q"))
-			silent = 1;
-		else
-			usage(diff_files_usage);
-		argv++; argc--;
-	}
+	b = setup_revisions(argc, argv, &rev, NULL, diff_files_ost);
+	if (b->argc)
+		usage(diff_files_usage);
 	/*
 	 * Make sure there are NO revision (i.e. pending object) parameter,
 	 * rev.max_count is reasonable (0 <= n <= 3),
diff --git a/diff-index.c b/diff-index.c
index 8c9f601..92052dc 100644
--- a/diff-index.c
+++ b/diff-index.c
@@ -2,6 +2,8 @@ #include "cache.h"
 #include "diff.h"
 #include "commit.h"
 #include "revision.h"
+#include "gitopt.h"
+#include "gitopt/diff.h"
 
 static const char diff_cache_usage[] =
 "git-diff-index [-m] [--cached] "
@@ -11,22 +13,17 @@ COMMON_DIFF_OPTIONS_HELP;
 int main(int argc, const char **argv)
 {
 	struct rev_info rev;
-	int cached = 0;
-	int i;
+	struct exec_args *b;
+	cached = 0;
 
 	git_config(git_diff_config);
 	init_revisions(&rev);
 	rev.abbrev = 0;
 
-	argc = setup_revisions(argc, argv, &rev, NULL);
-	for (i = 1; i < argc; i++) {
-		const char *arg = argv[i];
-			
-		if (!strcmp(arg, "--cached"))
-			cached = 1;
-		else
-			usage(diff_cache_usage);
-	}
+	b = setup_revisions(argc, argv, &rev, NULL, diff_index_ost);
+	if (b->argc)
+		usage(diff_cache_usage);
+
 	/*
 	 * Make sure there is one revision (i.e. pending object),
 	 * and there is no revision filtering parameters.
diff --git a/diff-tree.c b/diff-tree.c
index 7207867..240242c 100644
--- a/diff-tree.c
+++ b/diff-tree.c
@@ -2,6 +2,7 @@ #include "cache.h"
 #include "diff.h"
 #include "commit.h"
 #include "log-tree.h"
+#include "gitopt.h"
 
 static struct rev_info log_tree_opt;
 
@@ -58,6 +59,13 @@ static const char diff_tree_usage[] =
 "  --root        include the initial commit as diff against /dev/null\n"
 COMMON_DIFF_OPTIONS_HELP;
 
+static int read_stdin = 0;
+gitopt_eat(opt_stdin, read_stdin = 1;)
+static const struct opt_spec diff_tree_ost[] = {
+	{ "stdin",	0,	0,	0,	opt_stdin },
+	{ 0, 0 }
+};
+
 int main(int argc, const char **argv)
 {
 	int nr_sha1;
@@ -65,24 +73,17 @@ int main(int argc, const char **argv)
 	struct object *tree1, *tree2;
 	static struct rev_info *opt = &log_tree_opt;
 	struct object_list *list;
-	int read_stdin = 0;
+	struct exec_args *b;
 
 	git_config(git_diff_config);
 	nr_sha1 = 0;
 	init_revisions(opt);
 	opt->abbrev = 0;
 	opt->diff = 1;
-	argc = setup_revisions(argc, argv, opt, NULL);
-
-	while (--argc > 0) {
-		const char *arg = *++argv;
 
-		if (!strcmp(arg, "--stdin")) {
-			read_stdin = 1;
-			continue;
-		}
+	b = setup_revisions(argc, argv, opt, NULL, diff_tree_ost);
+	if (b->argc)
 		usage(diff_tree_usage);
-	}
 
 	/*
 	 * NOTE! "setup_revisions()" will have inserted the revisions
diff --git a/diff.c b/diff.c
index 5315270..3b56efc 100644
--- a/diff.c
+++ b/diff.c
@@ -9,6 +9,8 @@ #include "quote.h"
 #include "diff.h"
 #include "diffcore.h"
 #include "xdiff-interface.h"
+#include "gitopt.h"
+#include "gitopt/abbrev.h"
 
 static int use_size_cache;
 
@@ -407,7 +409,8 @@ static void builtin_diff(const char *nam
 			 struct diff_filespec *one,
 			 struct diff_filespec *two,
 			 const char *xfrm_msg,
-			 int complete_rewrite)
+			 int complete_rewrite,
+			 struct diff_options *o)
 {
 	mmfile_t mf1, mf2;
 	const char *lbl[2];
@@ -463,10 +466,9 @@ static void builtin_diff(const char *nam
 
 		ecbdata.label_path = lbl;
 		xpp.flags = XDF_NEED_MINIMAL;
-		xecfg.ctxlen = 3;
 		xecfg.flags = XDL_EMIT_FUNCNAMES;
 		if (!diffopts)
-			;
+			xecfg.ctxlen = o->ctxlen;
 		else if (!strncmp(diffopts, "--unified=", 10))
 			xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
 		else if (!strncmp(diffopts, "-u", 2))
@@ -928,7 +930,8 @@ static void run_diff_cmd(const char *pgm
 			 struct diff_filespec *one,
 			 struct diff_filespec *two,
 			 const char *xfrm_msg,
-			 int complete_rewrite)
+			 int complete_rewrite,
+			 struct diff_options *o)
 {
 	if (pgm) {
 		run_external_diff(pgm, name, other, one, two, xfrm_msg,
@@ -937,7 +940,7 @@ static void run_diff_cmd(const char *pgm
 	}
 	if (one && two)
 		builtin_diff(name, other ? other : name,
-			     one, two, xfrm_msg, complete_rewrite);
+			     one, two, xfrm_msg, complete_rewrite, o);
 	else
 		printf("* Unmerged path %s\n", name);
 }
@@ -971,7 +974,7 @@ static void run_diff(struct diff_filepai
 
 	if (DIFF_PAIR_UNMERGED(p)) {
 		/* unmerged */
-		run_diff_cmd(pgm, p->one->path, NULL, NULL, NULL, NULL, 0);
+		run_diff_cmd(pgm, p->one->path, NULL, NULL, NULL, NULL, 0, o);
 		return;
 	}
 
@@ -1041,15 +1044,15 @@ static void run_diff(struct diff_filepai
 		 * needs to be split into deletion and creation.
 		 */
 		struct diff_filespec *null = alloc_filespec(two->path);
-		run_diff_cmd(NULL, name, other, one, null, xfrm_msg, 0);
+		run_diff_cmd(NULL, name, other, one, null, xfrm_msg, 0, o);
 		free(null);
 		null = alloc_filespec(one->path);
-		run_diff_cmd(NULL, name, other, null, two, xfrm_msg, 0);
+		run_diff_cmd(NULL, name, other, null, two, xfrm_msg, 0, o);
 		free(null);
 	}
 	else
 		run_diff_cmd(pgm, name, other, one, two, xfrm_msg,
-			     complete_rewrite);
+			     complete_rewrite, o);
 
 	free(name_munged);
 	free(other_munged);
@@ -1086,6 +1089,7 @@ void diff_setup(struct diff_options *opt
 	options->line_termination = '\n';
 	options->break_opt = -1;
 	options->rename_limit = -1;
+	options->ctxlen = 3;
 
 	options->change = diff_change;
 	options->add_remove = diff_addremove;
@@ -1126,76 +1130,100 @@ int diff_setup_done(struct diff_options 
 	return 0;
 }
 
+static struct diff_options *g_opt = NULL; /* gitopt needs globals :x */
+static int rv_diff_opt_parse = 0;
+
+gitopt_eat_opt_int(opt_unified,
+		g_opt->output_format = DIFF_FORMAT_PATCH;
+		if (ea->argc) g_opt->ctxlen = strtol(ea->argv[0], NULL, 10);)
+gitopt_eat(opt_p, g_opt->output_format = DIFF_FORMAT_PATCH;)
+gitopt_eat(opt_patch_with_raw,
+		g_opt->output_format = DIFF_FORMAT_PATCH;
+		g_opt->with_raw = 1;)
+gitopt_eat(opt_raw, g_opt->output_format = DIFF_FORMAT_RAW;)
+gitopt_eat(opt_stat,
+		g_opt->output_format = DIFF_FORMAT_DIFFSTAT;)
+gitopt_eat(opt_patch_with_stat,
+		g_opt->output_format = DIFF_FORMAT_PATCH;
+		g_opt->with_stat = 1;)
+gitopt_eat(opt_z, g_opt->line_termination = 0;)
+gitopt_eat_one_arg(opt_l, g_opt->rename_limit = strtoul(ea->argv[0],NULL,10);)
+gitopt_eat(opt_full_index, g_opt->full_index = 1;)
+gitopt_eat(opt_name_only, g_opt->output_format = DIFF_FORMAT_NAME;)
+gitopt_eat(opt_name_status,
+			g_opt->output_format = DIFF_FORMAT_NAME_STATUS;)
+gitopt_eat(opt_R, g_opt->reverse_diff = 1;)
+gitopt_eat_one_arg(opt_S, g_opt->pickaxe = ea->argv[0];)
+gitopt_eat(opt_s, g_opt->output_format = DIFF_FORMAT_NO_OUTPUT;)
+gitopt_eat_one_arg(opt_O, g_opt->orderfile = ea->argv[0];)
+gitopt_eat_one_arg(opt_diff_filter, g_opt->filter = ea->argv[0];)
+gitopt_eat(opt_pickaxe_all, g_opt->pickaxe_opts = DIFF_PICKAXE_ALL;)
+gitopt_eat(opt_pickaxe_regex, g_opt->pickaxe_opts = DIFF_PICKAXE_REGEX;)
+gitopt_eat_opt_int(opt_B,
+	if ((g_opt->break_opt = diff_scoreopt_parse(*argv)) == -1)
+		rv_diff_opt_parse = -1;)
+gitopt_eat_opt_int(opt_M,
+	if ((g_opt->rename_score = diff_scoreopt_parse(*argv)) == -1)
+		rv_diff_opt_parse = -1;
+	g_opt->detect_rename = DIFF_DETECT_RENAME;)
+gitopt_eat_opt_int(opt_C,
+	if ((g_opt->rename_score = diff_scoreopt_parse(*argv)) == -1)
+		rv_diff_opt_parse = -1;
+	g_opt->detect_rename = DIFF_DETECT_COPY;)
+gitopt_eat(opt_find_copies_harder, g_opt->find_copies_harder = 1;)
+gitopt_opt_abbrev(g_opt->abbrev)
+
+static const struct opt_spec diff_ost[] = {
+	{ 0,			'p',	0,	0,	opt_p },
+	{ "unified",		'u',	"%s",	ARG_OPTINT,	opt_unified },
+	{ "raw",		0,	0,	0,	opt_raw },
+	{ "patch-with-raw",	0,	0,	0,	opt_patch_with_raw },
+	{ "stat",		0,	0,	0,	opt_stat },
+	{ "patch-with-stat",	0,	0,	0,	opt_patch_with_stat },
+	{ 0,			'z',	0,	0,	opt_z },
+	{ 0,			'l',	"%s",	ARG_INT,opt_l },
+	{ "full-index",		0,	0,	0,	opt_full_index },
+	{ "name-only",		0,	0,	0,	opt_name_only },
+	{ "name-status",	0,	0,	0,	opt_name_status },
+	{ 0,			'R',	0,	0,	opt_R },
+	{ 0,			'S',	"%s",	ARG_ONE,opt_S },
+	{ 0,			's',	0,	0,	opt_s },
+	{ 0,			'O',	"%s",	ARG_ONE, opt_O },
+	{ "diff-filter",	0,	"%s",	ARG_ONE, opt_diff_filter },
+	{ "pickaxe-all",	0,	0,	0,	opt_pickaxe_all },
+	{ "pickaxe-regex",	0,	0,	0,	opt_pickaxe_regex },
+	{ 0,			'B',	"%s",	ARG_OPTINT,opt_B },
+	{ 0,			'M',	"%s",	ARG_OPTINT,opt_M },
+	{ 0,			'C',	"%s",	ARG_OPTINT,opt_C },
+	{ "find-copies-harder",	0,	0,	0,	opt_find_copies_harder},
+	abbrev_ost_row,
+	{ 0, 0 }
+};
+
+static void diff_non_option_cb(struct exec_args *b, const int argc,
+					const char **argv, int *argc_pos)
+{
+	rv_diff_opt_parse = 0;
+}
+
 int diff_opt_parse(struct diff_options *options, const char **av, int ac)
 {
-	const char *arg = av[0];
-	if (!strcmp(arg, "-p") || !strcmp(arg, "-u"))
-		options->output_format = DIFF_FORMAT_PATCH;
-	else if (!strcmp(arg, "--patch-with-raw")) {
-		options->output_format = DIFF_FORMAT_PATCH;
-		options->with_raw = 1;
-	}
-	else if (!strcmp(arg, "--stat"))
-		options->output_format = DIFF_FORMAT_DIFFSTAT;
-	else if (!strcmp(arg, "--patch-with-stat")) {
-		options->output_format = DIFF_FORMAT_PATCH;
-		options->with_stat = 1;
-	}
-	else if (!strcmp(arg, "-z"))
-		options->line_termination = 0;
-	else if (!strncmp(arg, "-l", 2))
-		options->rename_limit = strtoul(arg+2, NULL, 10);
-	else if (!strcmp(arg, "--full-index"))
-		options->full_index = 1;
-	else if (!strcmp(arg, "--name-only"))
-		options->output_format = DIFF_FORMAT_NAME;
-	else if (!strcmp(arg, "--name-status"))
-		options->output_format = DIFF_FORMAT_NAME_STATUS;
-	else if (!strcmp(arg, "-R"))
-		options->reverse_diff = 1;
-	else if (!strncmp(arg, "-S", 2))
-		options->pickaxe = arg + 2;
-	else if (!strcmp(arg, "-s"))
-		options->output_format = DIFF_FORMAT_NO_OUTPUT;
-	else if (!strncmp(arg, "-O", 2))
-		options->orderfile = arg + 2;
-	else if (!strncmp(arg, "--diff-filter=", 14))
-		options->filter = arg + 14;
-	else if (!strcmp(arg, "--pickaxe-all"))
-		options->pickaxe_opts = DIFF_PICKAXE_ALL;
-	else if (!strcmp(arg, "--pickaxe-regex"))
-		options->pickaxe_opts = DIFF_PICKAXE_REGEX;
-	else if (!strncmp(arg, "-B", 2)) {
-		if ((options->break_opt =
-		     diff_scoreopt_parse(arg)) == -1)
-			return -1;
-	}
-	else if (!strncmp(arg, "-M", 2)) {
-		if ((options->rename_score =
-		     diff_scoreopt_parse(arg)) == -1)
-			return -1;
-		options->detect_rename = DIFF_DETECT_RENAME;
-	}
-	else if (!strncmp(arg, "-C", 2)) {
-		if ((options->rename_score =
-		     diff_scoreopt_parse(arg)) == -1)
-			return -1;
-		options->detect_rename = DIFF_DETECT_COPY;
-	}
-	else if (!strcmp(arg, "--find-copies-harder"))
-		options->find_copies_harder = 1;
-	else if (!strcmp(arg, "--abbrev"))
-		options->abbrev = DEFAULT_ABBREV;
-	else if (!strncmp(arg, "--abbrev=", 9)) {
-		options->abbrev = strtoul(arg + 9, NULL, 10);
-		if (options->abbrev < MINIMUM_ABBREV)
-			options->abbrev = MINIMUM_ABBREV;
-		else if (40 < options->abbrev)
-			options->abbrev = 40;
-	}
-	else
-		return 0;
-	return 1;
+	struct exec_args *a = new_exec_args(1);
+	int i = 0;
+	void (*old_non_option_cb)(struct exec_args *b, const int argc,
+				const char **argv, int *argc_pos);
+	g_opt = options;
+	rv_diff_opt_parse = 1;
+	gitopt_pass_through = 1;
+	old_non_option_cb = gitopt_non_option_cb;
+	gitopt_non_option_cb = diff_non_option_cb;
+
+	gitopt_parse_one_opt(a, a, diff_ost, ac, av, &i);
+
+	free_exec_args(a);
+	gitopt_non_option_cb = old_non_option_cb;
+
+	return rv_diff_opt_parse;
 }
 
 static int parse_num(const char **cp_p)
diff --git a/diff.h b/diff.h
index b3b2c4d..b5f016e 100644
--- a/diff.h
+++ b/diff.h
@@ -41,6 +41,7 @@ struct diff_options {
 	int rename_limit;
 	int setup;
 	int abbrev;
+	int ctxlen;
 
 	int nr_paths;
 	const char **paths;
diff --git a/gitopt/diff.h b/gitopt/diff.h
new file mode 100644
index 0000000..6530474
--- /dev/null
+++ b/gitopt/diff.h
@@ -0,0 +1,26 @@
+#ifndef GITOPT_DIFF_H
+#define GITOPT_DIFF_H
+
+static struct rev_info *g_rev;
+static int silent;
+static int cached;
+
+gitopt_eat(opt_base,		g_rev->max_count = 1;)
+gitopt_eat(opt_ours,		g_rev->max_count = 2;)
+gitopt_eat(opt_theres,		g_rev->max_count = 3;)
+gitopt_eat(opt_q,		silent = 1;)
+static const struct opt_spec diff_files_ost[] = {
+	{ "base",	0,	0,	0,	opt_base },
+	{ "ours",	0,	0,	0,	opt_ours },
+	{ "theres",	0,	0,	0,	opt_theres },
+	{ 0,		'q',	0,	0,	opt_q },
+	{ 0, 0 }
+};
+
+gitopt_eat(opt_cached,		cached = 1;)
+static const struct opt_spec diff_index_ost[] = {
+	{ "cached",	0,	0,	0,	opt_cached },
+	{ 0, 0 }
+};
+
+#endif /* GITOPT_DIFF_H */
diff --git a/http-push.c b/http-push.c
index b4327d9..9c16f3b 100644
--- a/http-push.c
+++ b/http-push.c
@@ -2499,7 +2499,7 @@ int main(int argc, char **argv)
 			commit_argc++;
 		}
 		init_revisions(&revs);
-		setup_revisions(commit_argc, commit_argv, &revs, NULL);
+		setup_revisions(commit_argc, commit_argv, &revs, NULL, NULL);
 		free(new_sha1_hex);
 		if (old_sha1_hex) {
 			free(old_sha1_hex);
diff --git a/rev-list.c b/rev-list.c
index 8b0ec38..3c72c59 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -7,6 +7,7 @@ #include "blob.h"
 #include "tree-walk.h"
 #include "diff.h"
 #include "revision.h"
+#include "gitopt.h"
 
 /* bits #0-15 in revision.h */
 
@@ -291,34 +292,31 @@ static void mark_edges_uninteresting(str
 	}
 }
 
+static struct rev_info *g_rev;
+gitopt_eat(opt_header,			g_rev->verbose_header = 1;)
+gitopt_eat(opt_timestamp,		show_timestamp = 1;)
+gitopt_eat(opt_bisect,			bisect_list = 1;)
+static const struct opt_spec rev_list_ost[] = {
+	{ "header",	0,	0,	0,	opt_header },
+	{ "timestamp",	0,	0,	0,	opt_timestamp },
+	{ "bisect",	0,	0,	0,	opt_bisect },
+	{ 0, 0 }
+};
+
 int main(int argc, const char **argv)
 {
 	struct commit_list *list;
-	int i;
+	struct exec_args *b;
 
 	init_revisions(&revs);
 	revs.abbrev = 0;
 	revs.commit_format = CMIT_FMT_UNSPECIFIED;
-	argc = setup_revisions(argc, argv, &revs, NULL);
-
-	for (i = 1 ; i < argc; i++) {
-		const char *arg = argv[i];
+	g_rev = &revs;
 
-		if (!strcmp(arg, "--header")) {
-			revs.verbose_header = 1;
-			continue;
-		}
-		if (!strcmp(arg, "--timestamp")) {
-			show_timestamp = 1;
-			continue;
-		}
-		if (!strcmp(arg, "--bisect")) {
-			bisect_list = 1;
-			continue;
-		}
+	b = setup_revisions(argc, argv, &revs, NULL, rev_list_ost);
+	if (b->argc)
 		usage(rev_list_usage);
 
-	}
 	if (revs.commit_format != CMIT_FMT_UNSPECIFIED) {
 		/* The command line has a --pretty  */
 		hdr_termination = '\n';
diff --git a/revision.c b/revision.c
index 2294b16..6769a48 100644
--- a/revision.c
+++ b/revision.c
@@ -6,6 +6,7 @@ #include "commit.h"
 #include "diff.h"
 #include "refs.h"
 #include "revision.h"
+#include "gitopt/abbrev.h"
 
 static char *path_name(struct name_path *path, const char *name)
 {
@@ -534,6 +535,198 @@ void init_revisions(struct rev_info *rev
 	diff_setup(&revs->diffopt);
 }
 
+static const char *g_def = NULL;
+
+/* I think I should just be able to use the all_* versions of these.. -ew */
+static struct rev_info *g_revs = NULL;
+static int g_flags = 0;
+static const struct opt_spec *g_extra_ost;
+
+gitopt_eat_int(opt_max_count,	g_revs->max_count = atoi(ea->argv[0]);)
+gitopt_eat_int(opt_max_age,	g_revs->max_age = atoi(ea->argv[0]);)
+gitopt_eat_int(opt_since,	g_revs->max_age = approxidate(ea->argv[0]);)
+gitopt_eat_int(opt_min_age,	g_revs->min_age = atoi(ea->argv[0]);)
+gitopt_eat_int(opt_until,	g_revs->min_age = approxidate(ea->argv[0]);)
+gitopt_eat(opt_all,		handle_all(g_revs, g_flags);)
+gitopt_eat(opt_not,		g_flags ^= UNINTERESTING;)
+gitopt_eat_arg(opt_default,	g_def = ea->argv[0];)
+gitopt_eat(opt_topo_order,	g_revs->topo_order = 1;)
+gitopt_eat(opt_date_order,	g_revs->topo_order = 1; g_revs->lifo = 0;)
+gitopt_eat(opt_parents,		g_revs->parents = 1;)
+gitopt_eat(opt_dense,		g_revs->dense = 1;)
+gitopt_eat(opt_sparse,		g_revs->dense = 0;)
+gitopt_eat(opt_remove_empty,	g_revs->remove_empty_trees = 1;)
+gitopt_eat(opt_no_merges,	g_revs->no_merges = 1;)
+gitopt_eat(opt_boundary,	g_revs->boundary = 1;)
+gitopt_eat(opt_objects,		g_revs->tag_objects = g_revs->tree_objects =
+					g_revs->blob_objects = 1;)
+gitopt_eat(opt_objects_edge,	g_revs->tag_objects = g_revs->tree_objects =
+				g_revs->blob_objects = g_revs->edge_hint = 1;)
+gitopt_eat(opt_unpacked,	g_revs->unpacked = 1;)
+gitopt_eat(opt_r,		g_revs->diff = g_revs->diffopt.recursive = 1;)
+gitopt_eat(opt_t,		g_revs->diff = g_revs->diffopt.recursive =
+					g_revs->diffopt.tree_in_recursive = 1;)
+gitopt_eat(opt_m,		g_revs->ignore_merges = 0;)
+gitopt_eat(opt_c,		g_revs->diff = g_revs->combine_merges = 1;
+				g_revs->dense_combined_merges = 0;)
+gitopt_eat(opt_cc,		g_revs->diff = g_revs->combine_merges =
+					g_revs->dense_combined_merges = 1;)
+gitopt_eat(opt_v,		g_revs->verbose_header = 1;)
+gitopt_eat_arg(opt_pretty,		g_revs->verbose_header = 1;
+				g_revs->commit_format = get_commit_format(
+								ea->argv[0]);)
+gitopt_eat(opt_root,		g_revs->show_root_diff = 1;)
+gitopt_eat(opt_no_commit_id,	g_revs->no_commit_id = 1;)
+gitopt_eat(opt_always,		g_revs->always_show_header = 1;)
+gitopt_opt_abbrev(g_revs->abbrev)
+gitopt_eat(opt_no_abbrev,	g_revs->abbrev = 0;)
+gitopt_eat(opt_abbrev_commit,	g_revs->abbrev_commit = 1;)
+gitopt_eat(opt_full_diff,	g_revs->full_diff = g_revs->diff = 1;)
+
+static const struct opt_spec setup_revisions_ost[] = {
+	{ "max-count",		'n',	"%s",	ARG_INT,	opt_max_count },
+	{ 0,			' ',	"%s",	ARG_INT,	opt_max_count },
+	{ "max-age",		0,	"%s",	ARG_INT,	opt_max_age },
+	{ "min-age",		0,	"%s",	ARG_INT,	opt_min_age },
+	{ "since",		0,	"%s",	ARG_ONE,	opt_since },
+	{ "after",		0,	"%s",	ARG_ONE,	opt_since },
+	{ "before",		0,	"%s",	ARG_ONE,	opt_until },
+	{ "until",		0,	"%s",	ARG_ONE,	opt_until },
+	{ "all",		0,	0,	0,		opt_all },
+	{ "not",		0,	0,	0,		opt_not },
+	{ "default",		0,	"%s",	ARG_ONE,	opt_default },
+	{ "topo-order",		0,	0,	0,	opt_topo_order },
+	{ "date-order",		0,	0,	0,	opt_date_order },
+	{ "parents",		0,	0,	0,	opt_parents },
+	{ "dense",		0,	0,	0,	opt_dense },
+	{ "sparse",		0,	0,	0,	opt_sparse },
+	{ "remove-empty",	0,	0,	0,	opt_remove_empty },
+	{ "no-merges",		0,	0,	0,	opt_no_merges },
+	{ "boundary",		0,	0,	0,	opt_boundary },
+	{ "objects",		0,	0,	0,	opt_objects },
+	{ "objects-edge",	0,	0,	0,	opt_objects_edge },
+	{ "unpacked",		0,	0,	0,	opt_unpacked },
+	{ 0,			'r',	0,	0,	opt_r },
+	{ 0,			't',	0,	0,	opt_t },
+	{ 0,			'm',	0,	0,	opt_m },
+	{ 0,			'c',	0,	0,	opt_c },
+	{ "cc",			0,	0,	0,	opt_cc },
+	{ 0,			'v',	0,	0,	opt_v },
+	{ "pretty",		0,	"%s",	ARG_ONE,	opt_pretty },
+	{ "root",		0,	0,	0,	opt_root },
+	{ "no-commit-id",	0,	0,	0,	opt_no_commit_id },
+	{ "always",		0,	0,	0,	opt_always },
+	{ "no-abbrev",		0,	0,	0,	opt_no_abbrev },
+	abbrev_ost_row,
+	{ "abbrev-commit",	0,	0,	0,	opt_abbrev_commit },
+	{ "full-diff",		0,	0,	0,	opt_full_diff },
+	{ 0, 0 }
+};
+
+/* call this for every non-option (and everything after "--") we have */
+static void setup_revisions_non_option_cb(struct exec_args *b,
+			const int argc, const char **argv, int *argc_pos)
+{
+	int i = *argc_pos;
+	const char *arg = argv[i];
+	unsigned char sha1[20];
+	struct object *object;
+	char *dotdot;
+	int local_flags;
+
+	if (arg[0] == '-') { /* handle diff options: */
+		int opts = diff_opt_parse(&(g_revs->diffopt),
+					argv + i, argc - 1);
+		if (opts > 0) {
+			g_revs->diff = 1;
+			*argc_pos += opts - 1;
+			return;
+		}
+		if (g_extra_ost) {
+			void (*old_non_option_cb)(struct exec_args *b,
+					const int argc, const char **argv,
+					int *argc_pos);
+			int j = 0;
+			old_non_option_cb = gitopt_non_option_cb;
+			gitopt_non_option_cb = gitopt_default_non_option_cb;
+			gitopt_parse_one_opt(b, b, g_extra_ost,
+						argc - i, argv + i, &j);
+			gitopt_non_option_cb = old_non_option_cb;
+			*argc_pos += j;
+		}
+		return;
+	}
+
+	/* otherwise it's a revision */
+	dotdot = strstr(arg, "..");
+	if (dotdot) {
+		unsigned char from_sha1[20];
+		const char *next = dotdot + 2;
+		const char *this = arg;
+		*dotdot = 0;
+		if (!*next)
+			next = "HEAD";
+		if (dotdot == arg)
+			this = "HEAD";
+		if (!get_sha1(this, from_sha1) &&
+		    !get_sha1(next, sha1)) {
+			struct object *exclude;
+			struct object *include;
+
+			exclude = get_reference(g_revs, this, from_sha1,
+						g_flags ^ UNINTERESTING);
+			include = get_reference(g_revs, next, sha1, g_flags);
+			if (!exclude || !include)
+				die("Invalid revision range %s..%s", arg, next);
+
+			if (!gitopt_dd_seen) {
+				*dotdot = '.';
+				verify_non_filename(g_revs->prefix, arg);
+			}
+			add_pending_object(g_revs, exclude, this);
+			add_pending_object(g_revs, include, next);
+			return;
+		}
+		*dotdot = '.';
+	}
+
+	dotdot = strstr(arg, "^@");
+	if (dotdot && !dotdot[2]) {
+		*dotdot = 0;
+		if (add_parents_only(g_revs, arg, g_flags))
+			return;
+		*dotdot = '^';
+	}
+	local_flags = 0;
+	if (*arg == '^') {
+		local_flags = UNINTERESTING;
+		arg++;
+	}
+	if (get_sha1(arg, sha1) < 0) {
+		int j;
+
+		if (gitopt_dd_seen || local_flags)
+			die("bad revision '%s'", arg);
+
+		/* If we didn't have a "--":
+		 * (1) all filenames must exist;
+		 * (2) all rev-args must not be interpretable
+		 *     as a valid filename.
+		 * but the latter we have checked in the main loop.
+		 */
+		for (j = *argc_pos; j < argc; j++)
+			verify_filename(g_revs->prefix, argv[j]);
+
+		g_revs->prune_data = get_pathspec(g_revs->prefix,
+						argv + *argc_pos);
+		return;
+	}
+	if (!gitopt_dd_seen)
+		verify_non_filename(g_revs->prefix, arg);
+	object = get_reference(g_revs, arg, sha1, g_flags ^ local_flags);
+	add_pending_object(g_revs, object, arg);
+}
+
 /*
  * Parse revision information, filling in the "rev_info" structure,
  * and removing the used arguments from the argument list.
@@ -541,14 +734,19 @@ void init_revisions(struct rev_info *rev
  * Returns the number of arguments left that weren't recognized
  * (which are also moved to the head of the argument list)
  */
-int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)
+struct exec_args *setup_revisions(int argc, const char **argv,
+				struct rev_info *revs, const char *def,
+				const struct opt_spec *extra_ost)
 {
-	int i, flags, seen_dashdash;
-	const char **unrecognized = argv + 1;
-	int left = 1;
+	int i;
+	struct exec_args *a, *b;
+
+	g_extra_ost = extra_ost;
+	g_def = def;
+	g_revs = revs;
+	gitopt_dd_seen = 0;
 
 	/* First, search for "--" */
-	seen_dashdash = 0;
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
 		if (strcmp(arg, "--"))
@@ -556,274 +754,24 @@ int setup_revisions(int argc, const char
 		argv[i] = NULL;
 		argc = i;
 		revs->prune_data = get_pathspec(revs->prefix, argv + i + 1);
-		seen_dashdash = 1;
+		gitopt_dd_seen = 1;
 		break;
 	}
 
-	flags = 0;
-	for (i = 1; i < argc; i++) {
-		struct object *object;
-		const char *arg = argv[i];
-		unsigned char sha1[20];
-		char *dotdot;
-		int local_flags;
-
-		if (*arg == '-') {
-			int opts;
-			if (!strncmp(arg, "--max-count=", 12)) {
-				revs->max_count = atoi(arg + 12);
-				continue;
-			}
-			/* accept -<digit>, like traditional "head" */
-			if ((*arg == '-') && isdigit(arg[1])) {
-				revs->max_count = atoi(arg + 1);
-				continue;
-			}
-			if (!strcmp(arg, "-n")) {
-				if (argc <= i + 1)
-					die("-n requires an argument");
-				revs->max_count = atoi(argv[++i]);
-				continue;
-			}
-			if (!strncmp(arg,"-n",2)) {
-				revs->max_count = atoi(arg + 2);
-				continue;
-			}
-			if (!strncmp(arg, "--max-age=", 10)) {
-				revs->max_age = atoi(arg + 10);
-				continue;
-			}
-			if (!strncmp(arg, "--since=", 8)) {
-				revs->max_age = approxidate(arg + 8);
-				continue;
-			}
-			if (!strncmp(arg, "--after=", 8)) {
-				revs->max_age = approxidate(arg + 8);
-				continue;
-			}
-			if (!strncmp(arg, "--min-age=", 10)) {
-				revs->min_age = atoi(arg + 10);
-				continue;
-			}
-			if (!strncmp(arg, "--before=", 9)) {
-				revs->min_age = approxidate(arg + 9);
-				continue;
-			}
-			if (!strncmp(arg, "--until=", 8)) {
-				revs->min_age = approxidate(arg + 8);
-				continue;
-			}
-			if (!strcmp(arg, "--all")) {
-				handle_all(revs, flags);
-				continue;
-			}
-			if (!strcmp(arg, "--not")) {
-				flags ^= UNINTERESTING;
-				continue;
-			}
-			if (!strcmp(arg, "--default")) {
-				if (++i >= argc)
-					die("bad --default argument");
-				def = argv[i];
-				continue;
-			}
-			if (!strcmp(arg, "--topo-order")) {
-				revs->topo_order = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--date-order")) {
-				revs->lifo = 0;
-				revs->topo_order = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--parents")) {
-				revs->parents = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--dense")) {
-				revs->dense = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--sparse")) {
-				revs->dense = 0;
-				continue;
-			}
-			if (!strcmp(arg, "--remove-empty")) {
-				revs->remove_empty_trees = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--no-merges")) {
-				revs->no_merges = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--boundary")) {
-				revs->boundary = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--objects")) {
-				revs->tag_objects = 1;
-				revs->tree_objects = 1;
-				revs->blob_objects = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--objects-edge")) {
-				revs->tag_objects = 1;
-				revs->tree_objects = 1;
-				revs->blob_objects = 1;
-				revs->edge_hint = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--unpacked")) {
-				revs->unpacked = 1;
-				continue;
-			}
-			if (!strcmp(arg, "-r")) {
-				revs->diff = 1;
-				revs->diffopt.recursive = 1;
-				continue;
-			}
-			if (!strcmp(arg, "-t")) {
-				revs->diff = 1;
-				revs->diffopt.recursive = 1;
-				revs->diffopt.tree_in_recursive = 1;
-				continue;
-			}
-			if (!strcmp(arg, "-m")) {
-				revs->ignore_merges = 0;
-				continue;
-			}
-			if (!strcmp(arg, "-c")) {
-				revs->diff = 1;
-				revs->dense_combined_merges = 0;
-				revs->combine_merges = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--cc")) {
-				revs->diff = 1;
-				revs->dense_combined_merges = 1;
-				revs->combine_merges = 1;
-				continue;
-			}
-			if (!strcmp(arg, "-v")) {
-				revs->verbose_header = 1;
-				continue;
-			}
-			if (!strncmp(arg, "--pretty", 8)) {
-				revs->verbose_header = 1;
-				revs->commit_format = get_commit_format(arg+8);
-				continue;
-			}
-			if (!strcmp(arg, "--root")) {
-				revs->show_root_diff = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--no-commit-id")) {
-				revs->no_commit_id = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--always")) {
-				revs->always_show_header = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--no-abbrev")) {
-				revs->abbrev = 0;
-				continue;
-			}
-			if (!strcmp(arg, "--abbrev")) {
-				revs->abbrev = DEFAULT_ABBREV;
-				continue;
-			}
-			if (!strcmp(arg, "--abbrev-commit")) {
-				revs->abbrev_commit = 1;
-				continue;
-			}
-			if (!strcmp(arg, "--full-diff")) {
-				revs->diff = 1;
-				revs->full_diff = 1;
-				continue;
-			}
-			opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
-			if (opts > 0) {
-				revs->diff = 1;
-				i += opts - 1;
-				continue;
-			}
-			*unrecognized++ = arg;
-			left++;
-			continue;
-		}
-		dotdot = strstr(arg, "..");
-		if (dotdot) {
-			unsigned char from_sha1[20];
-			const char *next = dotdot + 2;
-			const char *this = arg;
-			*dotdot = 0;
-			if (!*next)
-				next = "HEAD";
-			if (dotdot == arg)
-				this = "HEAD";
-			if (!get_sha1(this, from_sha1) &&
-			    !get_sha1(next, sha1)) {
-				struct object *exclude;
-				struct object *include;
-
-				exclude = get_reference(revs, this, from_sha1, flags ^ UNINTERESTING);
-				include = get_reference(revs, next, sha1, flags);
-				if (!exclude || !include)
-					die("Invalid revision range %s..%s", arg, next);
-
-				if (!seen_dashdash) {
-					*dotdot = '.';
-					verify_non_filename(revs->prefix, arg);
-				}
-				add_pending_object(revs, exclude, this);
-				add_pending_object(revs, include, next);
-				continue;
-			}
-			*dotdot = '.';
-		}
-		dotdot = strstr(arg, "^@");
-		if (dotdot && !dotdot[2]) {
-			*dotdot = 0;
-			if (add_parents_only(revs, arg, flags))
-				continue;
-			*dotdot = '^';
-		}
-		local_flags = 0;
-		if (*arg == '^') {
-			local_flags = UNINTERESTING;
-			arg++;
-		}
-		if (get_sha1(arg, sha1)) {
-			int j;
-
-			if (seen_dashdash || local_flags)
-				die("bad revision '%s'", arg);
-
-			/* If we didn't have a "--":
-			 * (1) all filenames must exist;
-			 * (2) all rev-args must not be interpretable
-			 *     as a valid filename.
-			 * but the latter we have checked in the main loop.
-			 */
-			for (j = i; j < argc; j++)
-				verify_filename(revs->prefix, argv[j]);
+	a = new_exec_args(argc);
+	b = new_exec_args(argc);
+	gitopt_pass_through = 1;
+	gitopt_non_option_cb = setup_revisions_non_option_cb;
+	if (gitopt_parse_ost_split(a, b, setup_revisions_ost, argc, argv))
+		return b;
 
-			revs->prune_data = get_pathspec(revs->prefix, argv + i);
-			break;
-		}
-		if (!seen_dashdash)
-			verify_non_filename(revs->prefix, arg);
-		object = get_reference(revs, arg, sha1, flags ^ local_flags);
-		add_pending_object(revs, object, arg);
-	}
-	if (def && !revs->pending_objects) {
+	if (g_def && !revs->pending_objects) {
 		unsigned char sha1[20];
 		struct object *object;
-		if (get_sha1(def, sha1))
-			die("bad default revision '%s'", def);
-		object = get_reference(revs, def, sha1, 0);
-		add_pending_object(revs, object, def);
+		if (get_sha1(g_def, sha1))
+			die("bad default revision '%s'", g_def);
+		object = get_reference(revs, g_def, sha1, 0);
+		add_pending_object(revs, object, g_def);
 	}
 
 	if (revs->topo_order || revs->unpacked)
@@ -844,7 +792,7 @@ int setup_revisions(int argc, const char
 	revs->diffopt.abbrev = revs->abbrev;
 	diff_setup_done(&revs->diffopt);
 
-	return left;
+	return b;
 }
 
 void prepare_revision_walk(struct rev_info *revs)
diff --git a/revision.h b/revision.h
index 48d7b4c..11a5820 100644
--- a/revision.h
+++ b/revision.h
@@ -1,6 +1,8 @@
 #ifndef REVISION_H
 #define REVISION_H
 
+#include "gitopt.h"
+
 #define SEEN		(1u<<0)
 #define UNINTERESTING   (1u<<1)
 #define TREECHANGE	(1u<<2)
@@ -81,7 +83,9 @@ extern int rev_same_tree_as_empty(struct
 extern int rev_compare_tree(struct rev_info *, struct tree *t1, struct tree *t2);
 
 extern void init_revisions(struct rev_info *revs);
-extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
+extern struct exec_args *setup_revisions(int argc, const char **argv,
+					struct rev_info *revs, const char *def,
+					const struct opt_spec *extra_ost);
 extern void prepare_revision_walk(struct rev_info *revs);
 extern struct commit *get_revision(struct rev_info *revs);
 
-- 
1.3.2.g0a3ae

-
: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]