{"thread":{"id":"4109","subject":"[PATCH 6/6] commit: allow --pretty= args to be abbreviated","startedAt":"2006-05-09T05:06:48Z","lastAt":"2006-05-11T20:19:33Z","messageCount":4,"participants":["Eric Wong"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"19770","messageId":"11471512123005-git-send-email-normalperson@yhbt.net","threadId":"4109","inReplyTo":"11471512121152-git-send-email-normalperson@yhbt.net","subject":"[PATCH 5/6] gitopt: convert setup_revisions(), and diff_opt_parse()","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-05-09T05:06:48Z","receivedAt":"2006-05-09T05:06:48Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"I've added --raw to diff_opt_parse() for consistency's sake:\n--patch-with-raw would otherwise be inconsistently abbreviated\nto --raw if it wasn't added.\n\n--with-r => --patch-with-raw works great\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n\n---\n\n builtin-diff.c |  109 ++++---------\n builtin-log.c  |    7 -\n commit.c       |   12 +\n diff-files.c   |   22 +--\n diff-index.c   |   19 +-\n diff-tree.c    |   21 +-\n diff.c         |  182 ++++++++++++---------\n diff.h         |    1 \n gitopt/diff.h  |   26 +++\n http-push.c    |    2 \n rev-list.c     |   34 ++--\n revision.c     |  484 +++++++++++++++++++++++++-------------------------------\n revision.h     |    6 +\n 13 files changed, 437 insertions(+), 488 deletions(-)\n create mode 100644 gitopt/diff.h\n\n28cbff1d1b543e8234acc6cada0fc889d4767a59\ndiff --git a/builtin-diff.c b/builtin-diff.c\nindex d3ac581..ff4a0ec 100644\n--- a/builtin-diff.c\n+++ b/builtin-diff.c\n@@ -12,6 +12,7 @@ #include \"diffcore.h\"\n #include \"revision.h\"\n #include \"log-tree.h\"\n #include \"builtin.h\"\n+#include \"gitopt/diff.h\"\n \n /* NEEDSWORK: struct object has place for name but we _do_\n  * know mode when we extracted the blob out of a tree, which\n@@ -29,22 +30,12 @@ static int builtin_diff_files(struct rev\n \t\t\t      int argc, const char **argv)\n {\n \tint silent = 0;\n-\twhile (1 < argc) {\n-\t\tconst char *arg = argv[1];\n-\t\tif (!strcmp(arg, \"--base\"))\n-\t\t\trevs->max_count = 1;\n-\t\telse if (!strcmp(arg, \"--ours\"))\n-\t\t\trevs->max_count = 2;\n-\t\telse if (!strcmp(arg, \"--theirs\"))\n-\t\t\trevs->max_count = 3;\n-\t\telse if (!strcmp(arg, \"-q\"))\n-\t\t\tsilent = 1;\n-\t\telse if (!strcmp(arg, \"--raw\"))\n-\t\t\trevs->diffopt.output_format = DIFF_FORMAT_RAW;\n-\t\telse\n-\t\t\tusage(builtin_diff_usage);\n-\t\targv++; argc--;\n-\t}\n+\tstruct exec_args *a;\n+\n+\tg_rev = revs;\n+\ta = new_exec_args(argc);\n+\tif (gitopt_parse_ost_split(a, a, diff_files_ost, argc, argv))\n+\t\tusage(builtin_diff_usage);\n \t/*\n \t * Make sure there are NO revision (i.e. pending object) parameter,\n \t * specified rev.max_count is reasonable (0 <= n <= 3), and\n@@ -107,14 +98,8 @@ static int builtin_diff_b_f(struct rev_i\n \t/* Blob vs file in the working tree*/\n \tstruct stat st;\n \n-\twhile (1 < argc) {\n-\t\tconst char *arg = argv[1];\n-\t\tif (!strcmp(arg, \"--raw\"))\n-\t\t\trevs->diffopt.output_format = DIFF_FORMAT_RAW;\n-\t\telse\n-\t\t\tusage(builtin_diff_usage);\n-\t\targv++; argc--;\n-\t}\n+\tif (argc)\n+\t\tusage(builtin_diff_usage);\n \tif (lstat(path, &st))\n \t\tdie(\"'%s': %s\", path, strerror(errno));\n \tif (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))\n@@ -135,14 +120,9 @@ static int builtin_diff_blobs(struct rev\n \t/* Blobs */\n \tunsigned mode = canon_mode(S_IFREG | 0644);\n \n-\twhile (1 < argc) {\n-\t\tconst char *arg = argv[1];\n-\t\tif (!strcmp(arg, \"--raw\"))\n-\t\t\trevs->diffopt.output_format = DIFF_FORMAT_RAW;\n-\t\telse\n-\t\t\tusage(builtin_diff_usage);\n-\t\targv++; argc--;\n-\t}\n+\tif (argc)\n+\t\tusage(builtin_diff_usage);\n+\n \tstuff_change(&revs->diffopt,\n \t\t     mode, mode,\n \t\t     blob[0].sha1, blob[1].sha1,\n@@ -155,17 +135,13 @@ static int builtin_diff_blobs(struct rev\n static int builtin_diff_index(struct rev_info *revs,\n \t\t\t      int argc, const char **argv)\n {\n-\tint cached = 0;\n-\twhile (1 < argc) {\n-\t\tconst char *arg = argv[1];\n-\t\tif (!strcmp(arg, \"--cached\"))\n-\t\t\tcached = 1;\n-\t\telse if (!strcmp(arg, \"--raw\"))\n-\t\t\trevs->diffopt.output_format = DIFF_FORMAT_RAW;\n-\t\telse\n-\t\t\tusage(builtin_diff_usage);\n-\t\targv++; argc--;\n-\t}\n+\tstruct exec_args *a;\n+\n+\tg_rev = revs;\n+\ta = new_exec_args(argc);\n+\tif (gitopt_parse_ost_split(a, a, diff_index_ost, argc, argv))\n+\t\tusage(builtin_diff_usage);\n+\n \t/*\n \t * Make sure there is one revision (i.e. pending object),\n \t * and there is no revision filtering parameters.\n@@ -183,14 +159,6 @@ static int builtin_diff_tree(struct rev_\n {\n \tconst unsigned char *(sha1[2]);\n \tint swap = 1;\n-\twhile (1 < argc) {\n-\t\tconst char *arg = argv[1];\n-\t\tif (!strcmp(arg, \"--raw\"))\n-\t\t\trevs->diffopt.output_format = DIFF_FORMAT_RAW;\n-\t\telse\n-\t\t\tusage(builtin_diff_usage);\n-\t\targv++; argc--;\n-\t}\n \n \t/* We saw two trees, ent[0] and ent[1].\n \t * unless ent[0] is unintesting, they are swapped\n@@ -212,14 +180,6 @@ static int builtin_diff_combined(struct \n \tconst unsigned char (*parent)[20];\n \tint i;\n \n-\twhile (1 < argc) {\n-\t\tconst char *arg = argv[1];\n-\t\tif (!strcmp(arg, \"--raw\"))\n-\t\t\trevs->diffopt.output_format = DIFF_FORMAT_RAW;\n-\t\telse\n-\t\t\tusage(builtin_diff_usage);\n-\t\targv++; argc--;\n-\t}\n \tif (!revs->dense_combined_merges && !revs->combine_merges)\n \t\trevs->dense_combined_merges = revs->combine_merges = 1;\n \tparent = xmalloc(ents * sizeof(*parent));\n@@ -250,6 +210,7 @@ int cmd_diff(int argc, const char **argv\n \tint ents = 0, blobs = 0, paths = 0;\n \tconst char *path = NULL;\n \tstruct blobinfo blob[2];\n+\tstruct exec_args *b;\n \n \t/*\n \t * We could get N tree-ish in the rev.pending_objects list.\n@@ -274,23 +235,14 @@ int cmd_diff(int argc, const char **argv\n \tgit_config(git_diff_config);\n \tinit_revisions(&rev);\n \trev.diffopt.output_format = DIFF_FORMAT_PATCH;\n+\tcached = 0;\n \n-\targc = setup_revisions(argc, argv, &rev, NULL);\n+\tb = setup_revisions(argc, argv, &rev, NULL, diff_index_ost);\n \t/* Do we have --cached and not have a pending object, then\n \t * default to HEAD by hand.  Eek.\n \t */\n-\tif (!rev.pending_objects) {\n-\t\tint i;\n-\t\tfor (i = 1; i < argc; i++) {\n-\t\t\tconst char *arg = argv[i];\n-\t\t\tif (!strcmp(arg, \"--\"))\n-\t\t\t\tbreak;\n-\t\t\telse if (!strcmp(arg, \"--cached\")) {\n-\t\t\t\tadd_head(&rev);\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\t}\n+\tif (!rev.pending_objects && cached)\n+\t\tadd_head(&rev);\n \n \tfor (list = rev.pending_objects; list; list = list->next) {\n \t\tstruct object *obj = list->item;\n@@ -340,17 +292,18 @@ int cmd_diff(int argc, const char **argv\n \tif (!ents) {\n \t\tswitch (blobs) {\n \t\tcase 0:\n-\t\t\treturn builtin_diff_files(&rev, argc, argv);\n+\t\t\treturn builtin_diff_files(&rev, b->argc, b->argv);\n \t\t\tbreak;\n \t\tcase 1:\n \t\t\tif (paths != 1)\n \t\t\t\tusage(builtin_diff_usage);\n-\t\t\treturn builtin_diff_b_f(&rev, argc, argv, blob, path);\n+\t\t\treturn builtin_diff_b_f(&rev, b->argc, b->argv,\n+\t\t\t\t\t\tblob, path);\n \t\t\tbreak;\n \t\tcase 2:\n \t\t\tif (paths)\n \t\t\t\tusage(builtin_diff_usage);\n-\t\t\treturn builtin_diff_blobs(&rev, argc, argv, blob);\n+\t\t\treturn builtin_diff_blobs(&rev, b->argc, b->argv, blob);\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tusage(builtin_diff_usage);\n@@ -359,10 +312,10 @@ int cmd_diff(int argc, const char **argv\n \telse if (blobs)\n \t\tusage(builtin_diff_usage);\n \telse if (ents == 1)\n-\t\treturn builtin_diff_index(&rev, argc, argv);\n+\t\treturn builtin_diff_index(&rev, b->argc, b->argv);\n \telse if (ents == 2)\n-\t\treturn builtin_diff_tree(&rev, argc, argv, ent);\n+\t\treturn builtin_diff_tree(&rev, b->argc, b->argv, ent);\n \telse\n-\t\treturn builtin_diff_combined(&rev, argc, argv, ent, ents);\n+\t\treturn builtin_diff_combined(&rev, b->argc, b->argv, ent, ents);\n \tusage(builtin_diff_usage);\n }\ndiff --git a/builtin-log.c b/builtin-log.c\nindex 69f2911..b004bc5 100644\n--- a/builtin-log.c\n+++ b/builtin-log.c\n@@ -14,14 +14,15 @@ static int cmd_log_wc(int argc, const ch\n \t\t      struct rev_info *rev)\n {\n \tstruct commit *commit;\n+\tstruct exec_args *b;\n \n \trev->abbrev = DEFAULT_ABBREV;\n \trev->commit_format = CMIT_FMT_DEFAULT;\n \trev->verbose_header = 1;\n-\targc = setup_revisions(argc, argv, rev, \"HEAD\");\n+\tb = setup_revisions(argc, argv, rev, \"HEAD\", NULL);\n \n-\tif (argc > 1)\n-\t\tdie(\"unrecognized argument: %s\", argv[1]);\n+\tif (b->argc)\n+\t\tdie(\"unrecognized argument: %s\", b->argv[0]);\n \n \tprepare_revision_walk(rev);\n \tsetup_pager();\ndiff --git a/commit.c b/commit.c\nindex 2717dd8..a056b25 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -26,17 +26,17 @@ enum cmit_fmt get_commit_format(const ch\n {\n \tif (!*arg)\n \t\treturn CMIT_FMT_DEFAULT;\n-\tif (!strcmp(arg, \"=raw\"))\n+\tif (!strcmp(arg, \"raw\"))\n \t\treturn CMIT_FMT_RAW;\n-\tif (!strcmp(arg, \"=medium\"))\n+\tif (!strcmp(arg, \"medium\"))\n \t\treturn CMIT_FMT_MEDIUM;\n-\tif (!strcmp(arg, \"=short\"))\n+\tif (!strcmp(arg, \"short\"))\n \t\treturn CMIT_FMT_SHORT;\n-\tif (!strcmp(arg, \"=full\"))\n+\tif (!strcmp(arg, \"full\"))\n \t\treturn CMIT_FMT_FULL;\n-\tif (!strcmp(arg, \"=fuller\"))\n+\tif (!strcmp(arg, \"fuller\"))\n \t\treturn CMIT_FMT_FULLER;\n-\tif (!strcmp(arg, \"=oneline\"))\n+\tif (!strcmp(arg, \"oneline\"))\n \t\treturn CMIT_FMT_ONELINE;\n \tdie(\"invalid --pretty format\");\n }\ndiff --git a/diff-files.c b/diff-files.c\nindex b9d193d..e5b69f4 100644\n--- a/diff-files.c\n+++ b/diff-files.c\n@@ -7,6 +7,7 @@ #include \"cache.h\"\n #include \"diff.h\"\n #include \"commit.h\"\n #include \"revision.h\"\n+#include \"gitopt/diff.h\"\n \n static const char diff_files_usage[] =\n \"git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]\"\n@@ -15,26 +16,17 @@ COMMON_DIFF_OPTIONS_HELP;\n int main(int argc, const char **argv)\n {\n \tstruct rev_info rev;\n-\tint silent = 0;\n+\tstruct exec_args *b;\n \n+\tsilent = 0;\n \tgit_config(git_diff_config);\n \tinit_revisions(&rev);\n \trev.abbrev = 0;\n+\tg_rev = &rev;\n \n-\targc = setup_revisions(argc, argv, &rev, NULL);\n-\twhile (1 < argc && argv[1][0] == '-') {\n-\t\tif (!strcmp(argv[1], \"--base\"))\n-\t\t\trev.max_count = 1;\n-\t\telse if (!strcmp(argv[1], \"--ours\"))\n-\t\t\trev.max_count = 2;\n-\t\telse if (!strcmp(argv[1], \"--theirs\"))\n-\t\t\trev.max_count = 3;\n-\t\telse if (!strcmp(argv[1], \"-q\"))\n-\t\t\tsilent = 1;\n-\t\telse\n-\t\t\tusage(diff_files_usage);\n-\t\targv++; argc--;\n-\t}\n+\tb = setup_revisions(argc, argv, &rev, NULL, diff_files_ost);\n+\tif (b->argc)\n+\t\tusage(diff_files_usage);\n \t/*\n \t * Make sure there are NO revision (i.e. pending object) parameter,\n \t * rev.max_count is reasonable (0 <= n <= 3),\ndiff --git a/diff-index.c b/diff-index.c\nindex 8c9f601..92052dc 100644\n--- a/diff-index.c\n+++ b/diff-index.c\n@@ -2,6 +2,8 @@ #include \"cache.h\"\n #include \"diff.h\"\n #include \"commit.h\"\n #include \"revision.h\"\n+#include \"gitopt.h\"\n+#include \"gitopt/diff.h\"\n \n static const char diff_cache_usage[] =\n \"git-diff-index [-m] [--cached] \"\n@@ -11,22 +13,17 @@ COMMON_DIFF_OPTIONS_HELP;\n int main(int argc, const char **argv)\n {\n \tstruct rev_info rev;\n-\tint cached = 0;\n-\tint i;\n+\tstruct exec_args *b;\n+\tcached = 0;\n \n \tgit_config(git_diff_config);\n \tinit_revisions(&rev);\n \trev.abbrev = 0;\n \n-\targc = setup_revisions(argc, argv, &rev, NULL);\n-\tfor (i = 1; i < argc; i++) {\n-\t\tconst char *arg = argv[i];\n-\t\t\t\n-\t\tif (!strcmp(arg, \"--cached\"))\n-\t\t\tcached = 1;\n-\t\telse\n-\t\t\tusage(diff_cache_usage);\n-\t}\n+\tb = setup_revisions(argc, argv, &rev, NULL, diff_index_ost);\n+\tif (b->argc)\n+\t\tusage(diff_cache_usage);\n+\n \t/*\n \t * Make sure there is one revision (i.e. pending object),\n \t * and there is no revision filtering parameters.\ndiff --git a/diff-tree.c b/diff-tree.c\nindex 7207867..240242c 100644\n--- a/diff-tree.c\n+++ b/diff-tree.c\n@@ -2,6 +2,7 @@ #include \"cache.h\"\n #include \"diff.h\"\n #include \"commit.h\"\n #include \"log-tree.h\"\n+#include \"gitopt.h\"\n \n static struct rev_info log_tree_opt;\n \n@@ -58,6 +59,13 @@ static const char diff_tree_usage[] =\n \"  --root        include the initial commit as diff against /dev/null\\n\"\n COMMON_DIFF_OPTIONS_HELP;\n \n+static int read_stdin = 0;\n+gitopt_eat(opt_stdin, read_stdin = 1;)\n+static const struct opt_spec diff_tree_ost[] = {\n+\t{ \"stdin\",\t0,\t0,\t0,\topt_stdin },\n+\t{ 0, 0 }\n+};\n+\n int main(int argc, const char **argv)\n {\n \tint nr_sha1;\n@@ -65,24 +73,17 @@ int main(int argc, const char **argv)\n \tstruct object *tree1, *tree2;\n \tstatic struct rev_info *opt = &log_tree_opt;\n \tstruct object_list *list;\n-\tint read_stdin = 0;\n+\tstruct exec_args *b;\n \n \tgit_config(git_diff_config);\n \tnr_sha1 = 0;\n \tinit_revisions(opt);\n \topt->abbrev = 0;\n \topt->diff = 1;\n-\targc = setup_revisions(argc, argv, opt, NULL);\n-\n-\twhile (--argc > 0) {\n-\t\tconst char *arg = *++argv;\n \n-\t\tif (!strcmp(arg, \"--stdin\")) {\n-\t\t\tread_stdin = 1;\n-\t\t\tcontinue;\n-\t\t}\n+\tb = setup_revisions(argc, argv, opt, NULL, diff_tree_ost);\n+\tif (b->argc)\n \t\tusage(diff_tree_usage);\n-\t}\n \n \t/*\n \t * NOTE! \"setup_revisions()\" will have inserted the revisions\ndiff --git a/diff.c b/diff.c\nindex 5315270..3b56efc 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -9,6 +9,8 @@ #include \"quote.h\"\n #include \"diff.h\"\n #include \"diffcore.h\"\n #include \"xdiff-interface.h\"\n+#include \"gitopt.h\"\n+#include \"gitopt/abbrev.h\"\n \n static int use_size_cache;\n \n@@ -407,7 +409,8 @@ static void builtin_diff(const char *nam\n \t\t\t struct diff_filespec *one,\n \t\t\t struct diff_filespec *two,\n \t\t\t const char *xfrm_msg,\n-\t\t\t int complete_rewrite)\n+\t\t\t int complete_rewrite,\n+\t\t\t struct diff_options *o)\n {\n \tmmfile_t mf1, mf2;\n \tconst char *lbl[2];\n@@ -463,10 +466,9 @@ static void builtin_diff(const char *nam\n \n \t\tecbdata.label_path = lbl;\n \t\txpp.flags = XDF_NEED_MINIMAL;\n-\t\txecfg.ctxlen = 3;\n \t\txecfg.flags = XDL_EMIT_FUNCNAMES;\n \t\tif (!diffopts)\n-\t\t\t;\n+\t\t\txecfg.ctxlen = o->ctxlen;\n \t\telse if (!strncmp(diffopts, \"--unified=\", 10))\n \t\t\txecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);\n \t\telse if (!strncmp(diffopts, \"-u\", 2))\n@@ -928,7 +930,8 @@ static void run_diff_cmd(const char *pgm\n \t\t\t struct diff_filespec *one,\n \t\t\t struct diff_filespec *two,\n \t\t\t const char *xfrm_msg,\n-\t\t\t int complete_rewrite)\n+\t\t\t int complete_rewrite,\n+\t\t\t struct diff_options *o)\n {\n \tif (pgm) {\n \t\trun_external_diff(pgm, name, other, one, two, xfrm_msg,\n@@ -937,7 +940,7 @@ static void run_diff_cmd(const char *pgm\n \t}\n \tif (one && two)\n \t\tbuiltin_diff(name, other ? other : name,\n-\t\t\t     one, two, xfrm_msg, complete_rewrite);\n+\t\t\t     one, two, xfrm_msg, complete_rewrite, o);\n \telse\n \t\tprintf(\"* Unmerged path %s\\n\", name);\n }\n@@ -971,7 +974,7 @@ static void run_diff(struct diff_filepai\n \n \tif (DIFF_PAIR_UNMERGED(p)) {\n \t\t/* unmerged */\n-\t\trun_diff_cmd(pgm, p->one->path, NULL, NULL, NULL, NULL, 0);\n+\t\trun_diff_cmd(pgm, p->one->path, NULL, NULL, NULL, NULL, 0, o);\n \t\treturn;\n \t}\n \n@@ -1041,15 +1044,15 @@ static void run_diff(struct diff_filepai\n \t\t * needs to be split into deletion and creation.\n \t\t */\n \t\tstruct diff_filespec *null = alloc_filespec(two->path);\n-\t\trun_diff_cmd(NULL, name, other, one, null, xfrm_msg, 0);\n+\t\trun_diff_cmd(NULL, name, other, one, null, xfrm_msg, 0, o);\n \t\tfree(null);\n \t\tnull = alloc_filespec(one->path);\n-\t\trun_diff_cmd(NULL, name, other, null, two, xfrm_msg, 0);\n+\t\trun_diff_cmd(NULL, name, other, null, two, xfrm_msg, 0, o);\n \t\tfree(null);\n \t}\n \telse\n \t\trun_diff_cmd(pgm, name, other, one, two, xfrm_msg,\n-\t\t\t     complete_rewrite);\n+\t\t\t     complete_rewrite, o);\n \n \tfree(name_munged);\n \tfree(other_munged);\n@@ -1086,6 +1089,7 @@ void diff_setup(struct diff_options *opt\n \toptions->line_termination = '\\n';\n \toptions->break_opt = -1;\n \toptions->rename_limit = -1;\n+\toptions->ctxlen = 3;\n \n \toptions->change = diff_change;\n \toptions->add_remove = diff_addremove;\n@@ -1126,76 +1130,100 @@ int diff_setup_done(struct diff_options \n \treturn 0;\n }\n \n+static struct diff_options *g_opt = NULL; /* gitopt needs globals :x */\n+static int rv_diff_opt_parse = 0;\n+\n+gitopt_eat_opt_int(opt_unified,\n+\t\tg_opt->output_format = DIFF_FORMAT_PATCH;\n+\t\tif (ea->argc) g_opt->ctxlen = strtol(ea->argv[0], NULL, 10);)\n+gitopt_eat(opt_p, g_opt->output_format = DIFF_FORMAT_PATCH;)\n+gitopt_eat(opt_patch_with_raw,\n+\t\tg_opt->output_format = DIFF_FORMAT_PATCH;\n+\t\tg_opt->with_raw = 1;)\n+gitopt_eat(opt_raw, g_opt->output_format = DIFF_FORMAT_RAW;)\n+gitopt_eat(opt_stat,\n+\t\tg_opt->output_format = DIFF_FORMAT_DIFFSTAT;)\n+gitopt_eat(opt_patch_with_stat,\n+\t\tg_opt->output_format = DIFF_FORMAT_PATCH;\n+\t\tg_opt->with_stat = 1;)\n+gitopt_eat(opt_z, g_opt->line_termination = 0;)\n+gitopt_eat_one_arg(opt_l, g_opt->rename_limit = strtoul(ea->argv[0],NULL,10);)\n+gitopt_eat(opt_full_index, g_opt->full_index = 1;)\n+gitopt_eat(opt_name_only, g_opt->output_format = DIFF_FORMAT_NAME;)\n+gitopt_eat(opt_name_status,\n+\t\t\tg_opt->output_format = DIFF_FORMAT_NAME_STATUS;)\n+gitopt_eat(opt_R, g_opt->reverse_diff = 1;)\n+gitopt_eat_one_arg(opt_S, g_opt->pickaxe = ea->argv[0];)\n+gitopt_eat(opt_s, g_opt->output_format = DIFF_FORMAT_NO_OUTPUT;)\n+gitopt_eat_one_arg(opt_O, g_opt->orderfile = ea->argv[0];)\n+gitopt_eat_one_arg(opt_diff_filter, g_opt->filter = ea->argv[0];)\n+gitopt_eat(opt_pickaxe_all, g_opt->pickaxe_opts = DIFF_PICKAXE_ALL;)\n+gitopt_eat(opt_pickaxe_regex, g_opt->pickaxe_opts = DIFF_PICKAXE_REGEX;)\n+gitopt_eat_opt_int(opt_B,\n+\tif ((g_opt->break_opt = diff_scoreopt_parse(*argv)) == -1)\n+\t\trv_diff_opt_parse = -1;)\n+gitopt_eat_opt_int(opt_M,\n+\tif ((g_opt->rename_score = diff_scoreopt_parse(*argv)) == -1)\n+\t\trv_diff_opt_parse = -1;\n+\tg_opt->detect_rename = DIFF_DETECT_RENAME;)\n+gitopt_eat_opt_int(opt_C,\n+\tif ((g_opt->rename_score = diff_scoreopt_parse(*argv)) == -1)\n+\t\trv_diff_opt_parse = -1;\n+\tg_opt->detect_rename = DIFF_DETECT_COPY;)\n+gitopt_eat(opt_find_copies_harder, g_opt->find_copies_harder = 1;)\n+gitopt_opt_abbrev(g_opt->abbrev)\n+\n+static const struct opt_spec diff_ost[] = {\n+\t{ 0,\t\t\t'p',\t0,\t0,\topt_p },\n+\t{ \"unified\",\t\t'u',\t\"%s\",\tARG_OPTINT,\topt_unified },\n+\t{ \"raw\",\t\t0,\t0,\t0,\topt_raw },\n+\t{ \"patch-with-raw\",\t0,\t0,\t0,\topt_patch_with_raw },\n+\t{ \"stat\",\t\t0,\t0,\t0,\topt_stat },\n+\t{ \"patch-with-stat\",\t0,\t0,\t0,\topt_patch_with_stat },\n+\t{ 0,\t\t\t'z',\t0,\t0,\topt_z },\n+\t{ 0,\t\t\t'l',\t\"%s\",\tARG_INT,opt_l },\n+\t{ \"full-index\",\t\t0,\t0,\t0,\topt_full_index },\n+\t{ \"name-only\",\t\t0,\t0,\t0,\topt_name_only },\n+\t{ \"name-status\",\t0,\t0,\t0,\topt_name_status },\n+\t{ 0,\t\t\t'R',\t0,\t0,\topt_R },\n+\t{ 0,\t\t\t'S',\t\"%s\",\tARG_ONE,opt_S },\n+\t{ 0,\t\t\t's',\t0,\t0,\topt_s },\n+\t{ 0,\t\t\t'O',\t\"%s\",\tARG_ONE, opt_O },\n+\t{ \"diff-filter\",\t0,\t\"%s\",\tARG_ONE, opt_diff_filter },\n+\t{ \"pickaxe-all\",\t0,\t0,\t0,\topt_pickaxe_all },\n+\t{ \"pickaxe-regex\",\t0,\t0,\t0,\topt_pickaxe_regex },\n+\t{ 0,\t\t\t'B',\t\"%s\",\tARG_OPTINT,opt_B },\n+\t{ 0,\t\t\t'M',\t\"%s\",\tARG_OPTINT,opt_M },\n+\t{ 0,\t\t\t'C',\t\"%s\",\tARG_OPTINT,opt_C },\n+\t{ \"find-copies-harder\",\t0,\t0,\t0,\topt_find_copies_harder},\n+\tabbrev_ost_row,\n+\t{ 0, 0 }\n+};\n+\n+static void diff_non_option_cb(struct exec_args *b, const int argc,\n+\t\t\t\t\tconst char **argv, int *argc_pos)\n+{\n+\trv_diff_opt_parse = 0;\n+}\n+\n int diff_opt_parse(struct diff_options *options, const char **av, int ac)\n {\n-\tconst char *arg = av[0];\n-\tif (!strcmp(arg, \"-p\") || !strcmp(arg, \"-u\"))\n-\t\toptions->output_format = DIFF_FORMAT_PATCH;\n-\telse if (!strcmp(arg, \"--patch-with-raw\")) {\n-\t\toptions->output_format = DIFF_FORMAT_PATCH;\n-\t\toptions->with_raw = 1;\n-\t}\n-\telse if (!strcmp(arg, \"--stat\"))\n-\t\toptions->output_format = DIFF_FORMAT_DIFFSTAT;\n-\telse if (!strcmp(arg, \"--patch-with-stat\")) {\n-\t\toptions->output_format = DIFF_FORMAT_PATCH;\n-\t\toptions->with_stat = 1;\n-\t}\n-\telse if (!strcmp(arg, \"-z\"))\n-\t\toptions->line_termination = 0;\n-\telse if (!strncmp(arg, \"-l\", 2))\n-\t\toptions->rename_limit = strtoul(arg+2, NULL, 10);\n-\telse if (!strcmp(arg, \"--full-index\"))\n-\t\toptions->full_index = 1;\n-\telse if (!strcmp(arg, \"--name-only\"))\n-\t\toptions->output_format = DIFF_FORMAT_NAME;\n-\telse if (!strcmp(arg, \"--name-status\"))\n-\t\toptions->output_format = DIFF_FORMAT_NAME_STATUS;\n-\telse if (!strcmp(arg, \"-R\"))\n-\t\toptions->reverse_diff = 1;\n-\telse if (!strncmp(arg, \"-S\", 2))\n-\t\toptions->pickaxe = arg + 2;\n-\telse if (!strcmp(arg, \"-s\"))\n-\t\toptions->output_format = DIFF_FORMAT_NO_OUTPUT;\n-\telse if (!strncmp(arg, \"-O\", 2))\n-\t\toptions->orderfile = arg + 2;\n-\telse if (!strncmp(arg, \"--diff-filter=\", 14))\n-\t\toptions->filter = arg + 14;\n-\telse if (!strcmp(arg, \"--pickaxe-all\"))\n-\t\toptions->pickaxe_opts = DIFF_PICKAXE_ALL;\n-\telse if (!strcmp(arg, \"--pickaxe-regex\"))\n-\t\toptions->pickaxe_opts = DIFF_PICKAXE_REGEX;\n-\telse if (!strncmp(arg, \"-B\", 2)) {\n-\t\tif ((options->break_opt =\n-\t\t     diff_scoreopt_parse(arg)) == -1)\n-\t\t\treturn -1;\n-\t}\n-\telse if (!strncmp(arg, \"-M\", 2)) {\n-\t\tif ((options->rename_score =\n-\t\t     diff_scoreopt_parse(arg)) == -1)\n-\t\t\treturn -1;\n-\t\toptions->detect_rename = DIFF_DETECT_RENAME;\n-\t}\n-\telse if (!strncmp(arg, \"-C\", 2)) {\n-\t\tif ((options->rename_score =\n-\t\t     diff_scoreopt_parse(arg)) == -1)\n-\t\t\treturn -1;\n-\t\toptions->detect_rename = DIFF_DETECT_COPY;\n-\t}\n-\telse if (!strcmp(arg, \"--find-copies-harder\"))\n-\t\toptions->find_copies_harder = 1;\n-\telse if (!strcmp(arg, \"--abbrev\"))\n-\t\toptions->abbrev = DEFAULT_ABBREV;\n-\telse if (!strncmp(arg, \"--abbrev=\", 9)) {\n-\t\toptions->abbrev = strtoul(arg + 9, NULL, 10);\n-\t\tif (options->abbrev < MINIMUM_ABBREV)\n-\t\t\toptions->abbrev = MINIMUM_ABBREV;\n-\t\telse if (40 < options->abbrev)\n-\t\t\toptions->abbrev = 40;\n-\t}\n-\telse\n-\t\treturn 0;\n-\treturn 1;\n+\tstruct exec_args *a = new_exec_args(1);\n+\tint i = 0;\n+\tvoid (*old_non_option_cb)(struct exec_args *b, const int argc,\n+\t\t\t\tconst char **argv, int *argc_pos);\n+\tg_opt = options;\n+\trv_diff_opt_parse = 1;\n+\tgitopt_pass_through = 1;\n+\told_non_option_cb = gitopt_non_option_cb;\n+\tgitopt_non_option_cb = diff_non_option_cb;\n+\n+\tgitopt_parse_one_opt(a, a, diff_ost, ac, av, &i);\n+\n+\tfree_exec_args(a);\n+\tgitopt_non_option_cb = old_non_option_cb;\n+\n+\treturn rv_diff_opt_parse;\n }\n \n static int parse_num(const char **cp_p)\ndiff --git a/diff.h b/diff.h\nindex b3b2c4d..b5f016e 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -41,6 +41,7 @@ struct diff_options {\n \tint rename_limit;\n \tint setup;\n \tint abbrev;\n+\tint ctxlen;\n \n \tint nr_paths;\n \tconst char **paths;\ndiff --git a/gitopt/diff.h b/gitopt/diff.h\nnew file mode 100644\nindex 0000000..6530474\n--- /dev/null\n+++ b/gitopt/diff.h\n@@ -0,0 +1,26 @@\n+#ifndef GITOPT_DIFF_H\n+#define GITOPT_DIFF_H\n+\n+static struct rev_info *g_rev;\n+static int silent;\n+static int cached;\n+\n+gitopt_eat(opt_base,\t\tg_rev->max_count = 1;)\n+gitopt_eat(opt_ours,\t\tg_rev->max_count = 2;)\n+gitopt_eat(opt_theres,\t\tg_rev->max_count = 3;)\n+gitopt_eat(opt_q,\t\tsilent = 1;)\n+static const struct opt_spec diff_files_ost[] = {\n+\t{ \"base\",\t0,\t0,\t0,\topt_base },\n+\t{ \"ours\",\t0,\t0,\t0,\topt_ours },\n+\t{ \"theres\",\t0,\t0,\t0,\topt_theres },\n+\t{ 0,\t\t'q',\t0,\t0,\topt_q },\n+\t{ 0, 0 }\n+};\n+\n+gitopt_eat(opt_cached,\t\tcached = 1;)\n+static const struct opt_spec diff_index_ost[] = {\n+\t{ \"cached\",\t0,\t0,\t0,\topt_cached },\n+\t{ 0, 0 }\n+};\n+\n+#endif /* GITOPT_DIFF_H */\ndiff --git a/http-push.c b/http-push.c\nindex b4327d9..9c16f3b 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -2499,7 +2499,7 @@ int main(int argc, char **argv)\n \t\t\tcommit_argc++;\n \t\t}\n \t\tinit_revisions(&revs);\n-\t\tsetup_revisions(commit_argc, commit_argv, &revs, NULL);\n+\t\tsetup_revisions(commit_argc, commit_argv, &revs, NULL, NULL);\n \t\tfree(new_sha1_hex);\n \t\tif (old_sha1_hex) {\n \t\t\tfree(old_sha1_hex);\ndiff --git a/rev-list.c b/rev-list.c\nindex 8b0ec38..3c72c59 100644\n--- a/rev-list.c\n+++ b/rev-list.c\n@@ -7,6 +7,7 @@ #include \"blob.h\"\n #include \"tree-walk.h\"\n #include \"diff.h\"\n #include \"revision.h\"\n+#include \"gitopt.h\"\n \n /* bits #0-15 in revision.h */\n \n@@ -291,34 +292,31 @@ static void mark_edges_uninteresting(str\n \t}\n }\n \n+static struct rev_info *g_rev;\n+gitopt_eat(opt_header,\t\t\tg_rev->verbose_header = 1;)\n+gitopt_eat(opt_timestamp,\t\tshow_timestamp = 1;)\n+gitopt_eat(opt_bisect,\t\t\tbisect_list = 1;)\n+static const struct opt_spec rev_list_ost[] = {\n+\t{ \"header\",\t0,\t0,\t0,\topt_header },\n+\t{ \"timestamp\",\t0,\t0,\t0,\topt_timestamp },\n+\t{ \"bisect\",\t0,\t0,\t0,\topt_bisect },\n+\t{ 0, 0 }\n+};\n+\n int main(int argc, const char **argv)\n {\n \tstruct commit_list *list;\n-\tint i;\n+\tstruct exec_args *b;\n \n \tinit_revisions(&revs);\n \trevs.abbrev = 0;\n \trevs.commit_format = CMIT_FMT_UNSPECIFIED;\n-\targc = setup_revisions(argc, argv, &revs, NULL);\n-\n-\tfor (i = 1 ; i < argc; i++) {\n-\t\tconst char *arg = argv[i];\n+\tg_rev = &revs;\n \n-\t\tif (!strcmp(arg, \"--header\")) {\n-\t\t\trevs.verbose_header = 1;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!strcmp(arg, \"--timestamp\")) {\n-\t\t\tshow_timestamp = 1;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tif (!strcmp(arg, \"--bisect\")) {\n-\t\t\tbisect_list = 1;\n-\t\t\tcontinue;\n-\t\t}\n+\tb = setup_revisions(argc, argv, &revs, NULL, rev_list_ost);\n+\tif (b->argc)\n \t\tusage(rev_list_usage);\n \n-\t}\n \tif (revs.commit_format != CMIT_FMT_UNSPECIFIED) {\n \t\t/* The command line has a --pretty  */\n \t\thdr_termination = '\\n';\ndiff --git a/revision.c b/revision.c\nindex 2294b16..6769a48 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -6,6 +6,7 @@ #include \"commit.h\"\n #include \"diff.h\"\n #include \"refs.h\"\n #include \"revision.h\"\n+#include \"gitopt/abbrev.h\"\n \n static char *path_name(struct name_path *path, const char *name)\n {\n@@ -534,6 +535,198 @@ void init_revisions(struct rev_info *rev\n \tdiff_setup(&revs->diffopt);\n }\n \n+static const char *g_def = NULL;\n+\n+/* I think I should just be able to use the all_* versions of these.. -ew */\n+static struct rev_info *g_revs = NULL;\n+static int g_flags = 0;\n+static const struct opt_spec *g_extra_ost;\n+\n+gitopt_eat_int(opt_max_count,\tg_revs->max_count = atoi(ea->argv[0]);)\n+gitopt_eat_int(opt_max_age,\tg_revs->max_age = atoi(ea->argv[0]);)\n+gitopt_eat_int(opt_since,\tg_revs->max_age = approxidate(ea->argv[0]);)\n+gitopt_eat_int(opt_min_age,\tg_revs->min_age = atoi(ea->argv[0]);)\n+gitopt_eat_int(opt_until,\tg_revs->min_age = approxidate(ea->argv[0]);)\n+gitopt_eat(opt_all,\t\thandle_all(g_revs, g_flags);)\n+gitopt_eat(opt_not,\t\tg_flags ^= UNINTERESTING;)\n+gitopt_eat_arg(opt_default,\tg_def = ea->argv[0];)\n+gitopt_eat(opt_topo_order,\tg_revs->topo_order = 1;)\n+gitopt_eat(opt_date_order,\tg_revs->topo_order = 1; g_revs->lifo = 0;)\n+gitopt_eat(opt_parents,\t\tg_revs->parents = 1;)\n+gitopt_eat(opt_dense,\t\tg_revs->dense = 1;)\n+gitopt_eat(opt_sparse,\t\tg_revs->dense = 0;)\n+gitopt_eat(opt_remove_empty,\tg_revs->remove_empty_trees = 1;)\n+gitopt_eat(opt_no_merges,\tg_revs->no_merges = 1;)\n+gitopt_eat(opt_boundary,\tg_revs->boundary = 1;)\n+gitopt_eat(opt_objects,\t\tg_revs->tag_objects = g_revs->tree_objects =\n+\t\t\t\t\tg_revs->blob_objects = 1;)\n+gitopt_eat(opt_objects_edge,\tg_revs->tag_objects = g_revs->tree_objects =\n+\t\t\t\tg_revs->blob_objects = g_revs->edge_hint = 1;)\n+gitopt_eat(opt_unpacked,\tg_revs->unpacked = 1;)\n+gitopt_eat(opt_r,\t\tg_revs->diff = g_revs->diffopt.recursive = 1;)\n+gitopt_eat(opt_t,\t\tg_revs->diff = g_revs->diffopt.recursive =\n+\t\t\t\t\tg_revs->diffopt.tree_in_recursive = 1;)\n+gitopt_eat(opt_m,\t\tg_revs->ignore_merges = 0;)\n+gitopt_eat(opt_c,\t\tg_revs->diff = g_revs->combine_merges = 1;\n+\t\t\t\tg_revs->dense_combined_merges = 0;)\n+gitopt_eat(opt_cc,\t\tg_revs->diff = g_revs->combine_merges =\n+\t\t\t\t\tg_revs->dense_combined_merges = 1;)\n+gitopt_eat(opt_v,\t\tg_revs->verbose_header = 1;)\n+gitopt_eat_arg(opt_pretty,\t\tg_revs->verbose_header = 1;\n+\t\t\t\tg_revs->commit_format = get_commit_format(\n+\t\t\t\t\t\t\t\tea->argv[0]);)\n+gitopt_eat(opt_root,\t\tg_revs->show_root_diff = 1;)\n+gitopt_eat(opt_no_commit_id,\tg_revs->no_commit_id = 1;)\n+gitopt_eat(opt_always,\t\tg_revs->always_show_header = 1;)\n+gitopt_opt_abbrev(g_revs->abbrev)\n+gitopt_eat(opt_no_abbrev,\tg_revs->abbrev = 0;)\n+gitopt_eat(opt_abbrev_commit,\tg_revs->abbrev_commit = 1;)\n+gitopt_eat(opt_full_diff,\tg_revs->full_diff = g_revs->diff = 1;)\n+\n+static const struct opt_spec setup_revisions_ost[] = {\n+\t{ \"max-count\",\t\t'n',\t\"%s\",\tARG_INT,\topt_max_count },\n+\t{ 0,\t\t\t' ',\t\"%s\",\tARG_INT,\topt_max_count },\n+\t{ \"max-age\",\t\t0,\t\"%s\",\tARG_INT,\topt_max_age },\n+\t{ \"min-age\",\t\t0,\t\"%s\",\tARG_INT,\topt_min_age },\n+\t{ \"since\",\t\t0,\t\"%s\",\tARG_ONE,\topt_since },\n+\t{ \"after\",\t\t0,\t\"%s\",\tARG_ONE,\topt_since },\n+\t{ \"before\",\t\t0,\t\"%s\",\tARG_ONE,\topt_until },\n+\t{ \"until\",\t\t0,\t\"%s\",\tARG_ONE,\topt_until },\n+\t{ \"all\",\t\t0,\t0,\t0,\t\topt_all },\n+\t{ \"not\",\t\t0,\t0,\t0,\t\topt_not },\n+\t{ \"default\",\t\t0,\t\"%s\",\tARG_ONE,\topt_default },\n+\t{ \"topo-order\",\t\t0,\t0,\t0,\topt_topo_order },\n+\t{ \"date-order\",\t\t0,\t0,\t0,\topt_date_order },\n+\t{ \"parents\",\t\t0,\t0,\t0,\topt_parents },\n+\t{ \"dense\",\t\t0,\t0,\t0,\topt_dense },\n+\t{ \"sparse\",\t\t0,\t0,\t0,\topt_sparse },\n+\t{ \"remove-empty\",\t0,\t0,\t0,\topt_remove_empty },\n+\t{ \"no-merges\",\t\t0,\t0,\t0,\topt_no_merges },\n+\t{ \"boundary\",\t\t0,\t0,\t0,\topt_boundary },\n+\t{ \"objects\",\t\t0,\t0,\t0,\topt_objects },\n+\t{ \"objects-edge\",\t0,\t0,\t0,\topt_objects_edge },\n+\t{ \"unpacked\",\t\t0,\t0,\t0,\topt_unpacked },\n+\t{ 0,\t\t\t'r',\t0,\t0,\topt_r },\n+\t{ 0,\t\t\t't',\t0,\t0,\topt_t },\n+\t{ 0,\t\t\t'm',\t0,\t0,\topt_m },\n+\t{ 0,\t\t\t'c',\t0,\t0,\topt_c },\n+\t{ \"cc\",\t\t\t0,\t0,\t0,\topt_cc },\n+\t{ 0,\t\t\t'v',\t0,\t0,\topt_v },\n+\t{ \"pretty\",\t\t0,\t\"%s\",\tARG_ONE,\topt_pretty },\n+\t{ \"root\",\t\t0,\t0,\t0,\topt_root },\n+\t{ \"no-commit-id\",\t0,\t0,\t0,\topt_no_commit_id },\n+\t{ \"always\",\t\t0,\t0,\t0,\topt_always },\n+\t{ \"no-abbrev\",\t\t0,\t0,\t0,\topt_no_abbrev },\n+\tabbrev_ost_row,\n+\t{ \"abbrev-commit\",\t0,\t0,\t0,\topt_abbrev_commit },\n+\t{ \"full-diff\",\t\t0,\t0,\t0,\topt_full_diff },\n+\t{ 0, 0 }\n+};\n+\n+/* call this for every non-option (and everything after \"--\") we have */\n+static void setup_revisions_non_option_cb(struct exec_args *b,\n+\t\t\tconst int argc, const char **argv, int *argc_pos)\n+{\n+\tint i = *argc_pos;\n+\tconst char *arg = argv[i];\n+\tunsigned char sha1[20];\n+\tstruct object *object;\n+\tchar *dotdot;\n+\tint local_flags;\n+\n+\tif (arg[0] == '-') { /* handle diff options: */\n+\t\tint opts = diff_opt_parse(&(g_revs->diffopt),\n+\t\t\t\t\targv + i, argc - 1);\n+\t\tif (opts > 0) {\n+\t\t\tg_revs->diff = 1;\n+\t\t\t*argc_pos += opts - 1;\n+\t\t\treturn;\n+\t\t}\n+\t\tif (g_extra_ost) {\n+\t\t\tvoid (*old_non_option_cb)(struct exec_args *b,\n+\t\t\t\t\tconst int argc, const char **argv,\n+\t\t\t\t\tint *argc_pos);\n+\t\t\tint j = 0;\n+\t\t\told_non_option_cb = gitopt_non_option_cb;\n+\t\t\tgitopt_non_option_cb = gitopt_default_non_option_cb;\n+\t\t\tgitopt_parse_one_opt(b, b, g_extra_ost,\n+\t\t\t\t\t\targc - i, argv + i, &j);\n+\t\t\tgitopt_non_option_cb = old_non_option_cb;\n+\t\t\t*argc_pos += j;\n+\t\t}\n+\t\treturn;\n+\t}\n+\n+\t/* otherwise it's a revision */\n+\tdotdot = strstr(arg, \"..\");\n+\tif (dotdot) {\n+\t\tunsigned char from_sha1[20];\n+\t\tconst char *next = dotdot + 2;\n+\t\tconst char *this = arg;\n+\t\t*dotdot = 0;\n+\t\tif (!*next)\n+\t\t\tnext = \"HEAD\";\n+\t\tif (dotdot == arg)\n+\t\t\tthis = \"HEAD\";\n+\t\tif (!get_sha1(this, from_sha1) &&\n+\t\t    !get_sha1(next, sha1)) {\n+\t\t\tstruct object *exclude;\n+\t\t\tstruct object *include;\n+\n+\t\t\texclude = get_reference(g_revs, this, from_sha1,\n+\t\t\t\t\t\tg_flags ^ UNINTERESTING);\n+\t\t\tinclude = get_reference(g_revs, next, sha1, g_flags);\n+\t\t\tif (!exclude || !include)\n+\t\t\t\tdie(\"Invalid revision range %s..%s\", arg, next);\n+\n+\t\t\tif (!gitopt_dd_seen) {\n+\t\t\t\t*dotdot = '.';\n+\t\t\t\tverify_non_filename(g_revs->prefix, arg);\n+\t\t\t}\n+\t\t\tadd_pending_object(g_revs, exclude, this);\n+\t\t\tadd_pending_object(g_revs, include, next);\n+\t\t\treturn;\n+\t\t}\n+\t\t*dotdot = '.';\n+\t}\n+\n+\tdotdot = strstr(arg, \"^@\");\n+\tif (dotdot && !dotdot[2]) {\n+\t\t*dotdot = 0;\n+\t\tif (add_parents_only(g_revs, arg, g_flags))\n+\t\t\treturn;\n+\t\t*dotdot = '^';\n+\t}\n+\tlocal_flags = 0;\n+\tif (*arg == '^') {\n+\t\tlocal_flags = UNINTERESTING;\n+\t\targ++;\n+\t}\n+\tif (get_sha1(arg, sha1) < 0) {\n+\t\tint j;\n+\n+\t\tif (gitopt_dd_seen || local_flags)\n+\t\t\tdie(\"bad revision '%s'\", arg);\n+\n+\t\t/* If we didn't have a \"--\":\n+\t\t * (1) all filenames must exist;\n+\t\t * (2) all rev-args must not be interpretable\n+\t\t *     as a valid filename.\n+\t\t * but the latter we have checked in the main loop.\n+\t\t */\n+\t\tfor (j = *argc_pos; j < argc; j++)\n+\t\t\tverify_filename(g_revs->prefix, argv[j]);\n+\n+\t\tg_revs->prune_data = get_pathspec(g_revs->prefix,\n+\t\t\t\t\t\targv + *argc_pos);\n+\t\treturn;\n+\t}\n+\tif (!gitopt_dd_seen)\n+\t\tverify_non_filename(g_revs->prefix, arg);\n+\tobject = get_reference(g_revs, arg, sha1, g_flags ^ local_flags);\n+\tadd_pending_object(g_revs, object, arg);\n+}\n+\n /*\n  * Parse revision information, filling in the \"rev_info\" structure,\n  * and removing the used arguments from the argument list.\n@@ -541,14 +734,19 @@ void init_revisions(struct rev_info *rev\n  * Returns the number of arguments left that weren't recognized\n  * (which are also moved to the head of the argument list)\n  */\n-int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)\n+struct exec_args *setup_revisions(int argc, const char **argv,\n+\t\t\t\tstruct rev_info *revs, const char *def,\n+\t\t\t\tconst struct opt_spec *extra_ost)\n {\n-\tint i, flags, seen_dashdash;\n-\tconst char **unrecognized = argv + 1;\n-\tint left = 1;\n+\tint i;\n+\tstruct exec_args *a, *b;\n+\n+\tg_extra_ost = extra_ost;\n+\tg_def = def;\n+\tg_revs = revs;\n+\tgitopt_dd_seen = 0;\n \n \t/* First, search for \"--\" */\n-\tseen_dashdash = 0;\n \tfor (i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \t\tif (strcmp(arg, \"--\"))\n@@ -556,274 +754,24 @@ int setup_revisions(int argc, const char\n \t\targv[i] = NULL;\n \t\targc = i;\n \t\trevs->prune_data = get_pathspec(revs->prefix, argv + i + 1);\n-\t\tseen_dashdash = 1;\n+\t\tgitopt_dd_seen = 1;\n \t\tbreak;\n \t}\n \n-\tflags = 0;\n-\tfor (i = 1; i < argc; i++) {\n-\t\tstruct object *object;\n-\t\tconst char *arg = argv[i];\n-\t\tunsigned char sha1[20];\n-\t\tchar *dotdot;\n-\t\tint local_flags;\n-\n-\t\tif (*arg == '-') {\n-\t\t\tint opts;\n-\t\t\tif (!strncmp(arg, \"--max-count=\", 12)) {\n-\t\t\t\trevs->max_count = atoi(arg + 12);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\t/* accept -<digit>, like traditional \"head\" */\n-\t\t\tif ((*arg == '-') && isdigit(arg[1])) {\n-\t\t\t\trevs->max_count = atoi(arg + 1);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"-n\")) {\n-\t\t\t\tif (argc <= i + 1)\n-\t\t\t\t\tdie(\"-n requires an argument\");\n-\t\t\t\trevs->max_count = atoi(argv[++i]);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strncmp(arg,\"-n\",2)) {\n-\t\t\t\trevs->max_count = atoi(arg + 2);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strncmp(arg, \"--max-age=\", 10)) {\n-\t\t\t\trevs->max_age = atoi(arg + 10);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strncmp(arg, \"--since=\", 8)) {\n-\t\t\t\trevs->max_age = approxidate(arg + 8);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strncmp(arg, \"--after=\", 8)) {\n-\t\t\t\trevs->max_age = approxidate(arg + 8);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strncmp(arg, \"--min-age=\", 10)) {\n-\t\t\t\trevs->min_age = atoi(arg + 10);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strncmp(arg, \"--before=\", 9)) {\n-\t\t\t\trevs->min_age = approxidate(arg + 9);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strncmp(arg, \"--until=\", 8)) {\n-\t\t\t\trevs->min_age = approxidate(arg + 8);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--all\")) {\n-\t\t\t\thandle_all(revs, flags);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--not\")) {\n-\t\t\t\tflags ^= UNINTERESTING;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--default\")) {\n-\t\t\t\tif (++i >= argc)\n-\t\t\t\t\tdie(\"bad --default argument\");\n-\t\t\t\tdef = argv[i];\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--topo-order\")) {\n-\t\t\t\trevs->topo_order = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--date-order\")) {\n-\t\t\t\trevs->lifo = 0;\n-\t\t\t\trevs->topo_order = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--parents\")) {\n-\t\t\t\trevs->parents = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--dense\")) {\n-\t\t\t\trevs->dense = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--sparse\")) {\n-\t\t\t\trevs->dense = 0;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--remove-empty\")) {\n-\t\t\t\trevs->remove_empty_trees = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--no-merges\")) {\n-\t\t\t\trevs->no_merges = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--boundary\")) {\n-\t\t\t\trevs->boundary = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--objects\")) {\n-\t\t\t\trevs->tag_objects = 1;\n-\t\t\t\trevs->tree_objects = 1;\n-\t\t\t\trevs->blob_objects = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--objects-edge\")) {\n-\t\t\t\trevs->tag_objects = 1;\n-\t\t\t\trevs->tree_objects = 1;\n-\t\t\t\trevs->blob_objects = 1;\n-\t\t\t\trevs->edge_hint = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--unpacked\")) {\n-\t\t\t\trevs->unpacked = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"-r\")) {\n-\t\t\t\trevs->diff = 1;\n-\t\t\t\trevs->diffopt.recursive = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"-t\")) {\n-\t\t\t\trevs->diff = 1;\n-\t\t\t\trevs->diffopt.recursive = 1;\n-\t\t\t\trevs->diffopt.tree_in_recursive = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"-m\")) {\n-\t\t\t\trevs->ignore_merges = 0;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"-c\")) {\n-\t\t\t\trevs->diff = 1;\n-\t\t\t\trevs->dense_combined_merges = 0;\n-\t\t\t\trevs->combine_merges = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--cc\")) {\n-\t\t\t\trevs->diff = 1;\n-\t\t\t\trevs->dense_combined_merges = 1;\n-\t\t\t\trevs->combine_merges = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"-v\")) {\n-\t\t\t\trevs->verbose_header = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strncmp(arg, \"--pretty\", 8)) {\n-\t\t\t\trevs->verbose_header = 1;\n-\t\t\t\trevs->commit_format = get_commit_format(arg+8);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--root\")) {\n-\t\t\t\trevs->show_root_diff = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--no-commit-id\")) {\n-\t\t\t\trevs->no_commit_id = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--always\")) {\n-\t\t\t\trevs->always_show_header = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--no-abbrev\")) {\n-\t\t\t\trevs->abbrev = 0;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--abbrev\")) {\n-\t\t\t\trevs->abbrev = DEFAULT_ABBREV;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--abbrev-commit\")) {\n-\t\t\t\trevs->abbrev_commit = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--full-diff\")) {\n-\t\t\t\trevs->diff = 1;\n-\t\t\t\trevs->full_diff = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\topts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);\n-\t\t\tif (opts > 0) {\n-\t\t\t\trevs->diff = 1;\n-\t\t\t\ti += opts - 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\t*unrecognized++ = arg;\n-\t\t\tleft++;\n-\t\t\tcontinue;\n-\t\t}\n-\t\tdotdot = strstr(arg, \"..\");\n-\t\tif (dotdot) {\n-\t\t\tunsigned char from_sha1[20];\n-\t\t\tconst char *next = dotdot + 2;\n-\t\t\tconst char *this = arg;\n-\t\t\t*dotdot = 0;\n-\t\t\tif (!*next)\n-\t\t\t\tnext = \"HEAD\";\n-\t\t\tif (dotdot == arg)\n-\t\t\t\tthis = \"HEAD\";\n-\t\t\tif (!get_sha1(this, from_sha1) &&\n-\t\t\t    !get_sha1(next, sha1)) {\n-\t\t\t\tstruct object *exclude;\n-\t\t\t\tstruct object *include;\n-\n-\t\t\t\texclude = get_reference(revs, this, from_sha1, flags ^ UNINTERESTING);\n-\t\t\t\tinclude = get_reference(revs, next, sha1, flags);\n-\t\t\t\tif (!exclude || !include)\n-\t\t\t\t\tdie(\"Invalid revision range %s..%s\", arg, next);\n-\n-\t\t\t\tif (!seen_dashdash) {\n-\t\t\t\t\t*dotdot = '.';\n-\t\t\t\t\tverify_non_filename(revs->prefix, arg);\n-\t\t\t\t}\n-\t\t\t\tadd_pending_object(revs, exclude, this);\n-\t\t\t\tadd_pending_object(revs, include, next);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\t*dotdot = '.';\n-\t\t}\n-\t\tdotdot = strstr(arg, \"^@\");\n-\t\tif (dotdot && !dotdot[2]) {\n-\t\t\t*dotdot = 0;\n-\t\t\tif (add_parents_only(revs, arg, flags))\n-\t\t\t\tcontinue;\n-\t\t\t*dotdot = '^';\n-\t\t}\n-\t\tlocal_flags = 0;\n-\t\tif (*arg == '^') {\n-\t\t\tlocal_flags = UNINTERESTING;\n-\t\t\targ++;\n-\t\t}\n-\t\tif (get_sha1(arg, sha1)) {\n-\t\t\tint j;\n-\n-\t\t\tif (seen_dashdash || local_flags)\n-\t\t\t\tdie(\"bad revision '%s'\", arg);\n-\n-\t\t\t/* If we didn't have a \"--\":\n-\t\t\t * (1) all filenames must exist;\n-\t\t\t * (2) all rev-args must not be interpretable\n-\t\t\t *     as a valid filename.\n-\t\t\t * but the latter we have checked in the main loop.\n-\t\t\t */\n-\t\t\tfor (j = i; j < argc; j++)\n-\t\t\t\tverify_filename(revs->prefix, argv[j]);\n+\ta = new_exec_args(argc);\n+\tb = new_exec_args(argc);\n+\tgitopt_pass_through = 1;\n+\tgitopt_non_option_cb = setup_revisions_non_option_cb;\n+\tif (gitopt_parse_ost_split(a, b, setup_revisions_ost, argc, argv))\n+\t\treturn b;\n \n-\t\t\trevs->prune_data = get_pathspec(revs->prefix, argv + i);\n-\t\t\tbreak;\n-\t\t}\n-\t\tif (!seen_dashdash)\n-\t\t\tverify_non_filename(revs->prefix, arg);\n-\t\tobject = get_reference(revs, arg, sha1, flags ^ local_flags);\n-\t\tadd_pending_object(revs, object, arg);\n-\t}\n-\tif (def && !revs->pending_objects) {\n+\tif (g_def && !revs->pending_objects) {\n \t\tunsigned char sha1[20];\n \t\tstruct object *object;\n-\t\tif (get_sha1(def, sha1))\n-\t\t\tdie(\"bad default revision '%s'\", def);\n-\t\tobject = get_reference(revs, def, sha1, 0);\n-\t\tadd_pending_object(revs, object, def);\n+\t\tif (get_sha1(g_def, sha1))\n+\t\t\tdie(\"bad default revision '%s'\", g_def);\n+\t\tobject = get_reference(revs, g_def, sha1, 0);\n+\t\tadd_pending_object(revs, object, g_def);\n \t}\n \n \tif (revs->topo_order || revs->unpacked)\n@@ -844,7 +792,7 @@ int setup_revisions(int argc, const char\n \trevs->diffopt.abbrev = revs->abbrev;\n \tdiff_setup_done(&revs->diffopt);\n \n-\treturn left;\n+\treturn b;\n }\n \n void prepare_revision_walk(struct rev_info *revs)\ndiff --git a/revision.h b/revision.h\nindex 48d7b4c..11a5820 100644\n--- a/revision.h\n+++ b/revision.h\n@@ -1,6 +1,8 @@\n #ifndef REVISION_H\n #define REVISION_H\n \n+#include \"gitopt.h\"\n+\n #define SEEN\t\t(1u<<0)\n #define UNINTERESTING   (1u<<1)\n #define TREECHANGE\t(1u<<2)\n@@ -81,7 +83,9 @@ extern int rev_same_tree_as_empty(struct\n extern int rev_compare_tree(struct rev_info *, struct tree *t1, struct tree *t2);\n \n extern void init_revisions(struct rev_info *revs);\n-extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);\n+extern struct exec_args *setup_revisions(int argc, const char **argv,\n+\t\t\t\t\tstruct rev_info *revs, const char *def,\n+\t\t\t\t\tconst struct opt_spec *extra_ost);\n extern void prepare_revision_walk(struct rev_info *revs);\n extern struct commit *get_revision(struct rev_info *revs);\n \n-- \n1.3.2.g0a3ae\n"},{"id":"19769","messageId":"11471512123998-git-send-email-normalperson@yhbt.net","threadId":"4109","inReplyTo":"11471512123005-git-send-email-normalperson@yhbt.net","subject":"[PATCH 6/6] commit: allow --pretty= args to be abbreviated","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-05-09T05:06:49Z","receivedAt":"2006-05-09T05:06:49Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Signed-off-by: Eric Wong <normalperson@yhbt.net>\n\n---\n\n commit.c |   42 +++++++++++++++++++++++++++++-------------\n 1 files changed, 29 insertions(+), 13 deletions(-)\n\n0a3aed7c25eca808b29f2318d5e4c087e03b9bfb\ndiff --git a/commit.c b/commit.c\nindex a056b25..055064a 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -22,23 +22,39 @@ struct sort_node\n \n const char *commit_type = \"commit\";\n \n+struct cmt_fmt_map {\n+\tconst char *n;\n+\tenum cmit_fmt v;\n+} cmt_fmts[] = {\n+\t{ \"raw\",\tCMIT_FMT_RAW },\n+\t{ \"medium\",\tCMIT_FMT_MEDIUM },\n+\t{ \"short\",\tCMIT_FMT_SHORT },\n+\t{ \"full\",\tCMIT_FMT_FULL },\n+\t{ \"fuller\",\tCMIT_FMT_FULLER },\n+\t{ \"oneline\",\tCMIT_FMT_ONELINE },\n+};\n+\n enum cmit_fmt get_commit_format(const char *arg)\n {\n+\tint i, found = -1;\n \tif (!*arg)\n \t\treturn CMIT_FMT_DEFAULT;\n-\tif (!strcmp(arg, \"raw\"))\n-\t\treturn CMIT_FMT_RAW;\n-\tif (!strcmp(arg, \"medium\"))\n-\t\treturn CMIT_FMT_MEDIUM;\n-\tif (!strcmp(arg, \"short\"))\n-\t\treturn CMIT_FMT_SHORT;\n-\tif (!strcmp(arg, \"full\"))\n-\t\treturn CMIT_FMT_FULL;\n-\tif (!strcmp(arg, \"fuller\"))\n-\t\treturn CMIT_FMT_FULLER;\n-\tif (!strcmp(arg, \"oneline\"))\n-\t\treturn CMIT_FMT_ONELINE;\n-\tdie(\"invalid --pretty format\");\n+\tfor (i = 0; i < ARRAY_SIZE(cmt_fmts); i++) {\n+\t\tif (!strcmp(arg, cmt_fmts[i].n))\n+\t\t\treturn cmt_fmts[i].v;\n+\t}\n+\n+\t/* look for abbreviations */\n+\tfor (i = 0; i < ARRAY_SIZE(cmt_fmts); i++) {\n+\t\tif (strstr(cmt_fmts[i].n, arg)) {\n+\t\t\tif (found >= 0)\n+\t\t\t\tdie(\"invalid --pretty format: %s\", arg);\n+\t\t\tfound = i;\n+\t\t}\n+\t}\n+\tif (found >= 0)\n+\t\treturn cmt_fmts[found].v;\n+\tdie(\"invalid --pretty format: %s\", arg);\n }\n \n static struct commit *check_commit(struct object *obj,\n-- \n1.3.2.g0a3ae\n"},{"id":"19772","messageId":"20060509071649.GB4591@hand.yhbt.net","threadId":"4109","inReplyTo":"11471512123005-git-send-email-normalperson@yhbt.net","subject":"Re: [PATCH 5/6] gitopt: convert setup_revisions(), and diff_opt_parse()","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-05-09T07:16:49Z","receivedAt":"2006-05-09T07:16:49Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Eric Wong <normalperson@yhbt.net> wrote:\n> I've added --raw to diff_opt_parse() for consistency's sake:\n> --patch-with-raw would otherwise be inconsistently abbreviated\n> to --raw if it wasn't added.\n\nI was looking for this patch, but then I realized it slipped in here.\n\nI've added --unified=<num>/-u<num> context here so I don't have to go\nthrough the awkwardness of setting GIT_DIFF_OPTS in the environment.\n\n-- \nEric Wong\n"},{"id":"19859","messageId":"20060511201933.GA19346@localdomain","threadId":"4109","inReplyTo":"11471512123005-git-send-email-normalperson@yhbt.net","subject":"Re: [PATCH 5/6] gitopt: convert setup_revisions(), and diff_opt_parse()","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-05-11T20:19:33Z","receivedAt":"2006-05-11T20:19:33Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"In other news, this patch is broken.  Bundled args won't work if some\nin the bundle are handled setup_revisions() and some are handled by\ndiff_opt_parse().\n\nI'll work on fixing this, as well (may take a while working mostly one-handed).\n\n-- \nEric Wong\n"}]}