{"thread":{"id":"14345","subject":"[PATCH 1/3] revisions: split handle_revision_opt from setup_revisions.","startedAt":"2008-07-08T13:19:32Z","lastAt":"2008-07-08T22:57:27Z","messageCount":6,"participants":["Pierre Habouzit","Linus Torvalds","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"82602","messageId":"1215523175-28436-1-git-send-email-madcoder@debian.org","threadId":"14345","inReplyTo":null,"subject":"[take 2] revision parsing made incremental","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-08T13:19:32Z","receivedAt":"2008-07-08T13:19:32Z","isPatch":false,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"Following Dscho's remarks, I reworked the series to avoid changing\nsetup_revisions semantics for now, and only exposed the part that groks\noptions (and keep pseudo revision arguments out).\n\nIt indeed makes the series smaller, even if the first patch is quite\nlong to read, and is just enough for simplifying git-blame in a very\nsatisfying way.\n\nThe series passes the testsuite, has no know blanks issues, and is\npushed to my public repository.\n"},{"id":"82599","messageId":"1215523175-28436-2-git-send-email-madcoder@debian.org","threadId":"14345","inReplyTo":"1215523175-28436-1-git-send-email-madcoder@debian.org","subject":"[PATCH 1/3] revisions: split handle_revision_opt from setup_revisions.","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-08T13:19:33Z","receivedAt":"2008-07-08T13:19:33Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"struct rev_info gains two new field:\n* .def to store --default argument;\n* .show_merge 1-bit field.\n\nhandle_revision_opt is able to deal with any revision option, and consumes\nthem, and leaves revision arguments or pseudo arguments (like --all,\n--not, ...) in place.\n\nFor now setup_revisions does a pass of handle_revision_opt again so that\ncode not using it in a parse-opt parser still work the same.\n\nSigned-off-by: Pierre Habouzit <madcoder@debian.org>\n---\n revision.c |  612 ++++++++++++++++++++++++++++--------------------------------\n revision.h |    4 +\n 2 files changed, 290 insertions(+), 326 deletions(-)\n\ndiff --git a/revision.c b/revision.c\nindex 0191160..3dbb7a8 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -974,6 +974,276 @@ static void add_ignore_packed(struct rev_info *revs, const char *name)\n \trevs->ignore_packed[num] = NULL;\n }\n \n+int handle_revision_opt(struct rev_info *revs, int argc, const char **argv,\n+\t\t\tint *unkc, const char **unkv)\n+{\n+\tconst char *arg = argv[0];\n+\n+\t/* pseudo revision arguments */\n+\tif (!strcmp(arg, \"--all\") || !strcmp(arg, \"--branches\") ||\n+\t    !strcmp(arg, \"--tags\") || !strcmp(arg, \"--remotes\") ||\n+\t    !strcmp(arg, \"--reflog\") || !strcmp(arg, \"--not\") ||\n+\t    !strcmp(arg, \"--no-walk\") || !strcmp(arg, \"--do-walk\"))\n+\t{\n+\t\tunkv[(*unkc)++] = arg;\n+\t\treturn 0;\n+\t}\n+\n+\tif (!prefixcmp(arg, \"--max-count=\")) {\n+\t\trevs->max_count = atoi(arg + 12);\n+\t}\n+\telse if (!prefixcmp(arg, \"--skip=\")) {\n+\t\trevs->skip_count = atoi(arg + 7);\n+\t}\n+\t/* accept -<digit>, like traditional \"head\" */\n+\telse if ((*arg == '-') && isdigit(arg[1])) {\n+\t\trevs->max_count = atoi(arg + 1);\n+\t}\n+\telse if (!strcmp(arg, \"-n\")) {\n+\t\tif (argc <= 1)\n+\t\t\treturn error(\"-n requires an argument\");\n+\t\trevs->max_count = atoi(argv[1]);\n+\t\treturn 2;\n+\t}\n+\telse if (!prefixcmp(arg, \"-n\")) {\n+\t\trevs->max_count = atoi(arg + 2);\n+\t}\n+\telse if (!prefixcmp(arg, \"--max-age=\")) {\n+\t\trevs->max_age = atoi(arg + 10);\n+\t}\n+\telse if (!prefixcmp(arg, \"--since=\")) {\n+\t\trevs->max_age = approxidate(arg + 8);\n+\t}\n+\telse if (!prefixcmp(arg, \"--after=\")) {\n+\t\trevs->max_age = approxidate(arg + 8);\n+\t}\n+\telse if (!prefixcmp(arg, \"--min-age=\")) {\n+\t\trevs->min_age = atoi(arg + 10);\n+\t}\n+\telse if (!prefixcmp(arg, \"--before=\")) {\n+\t\trevs->min_age = approxidate(arg + 9);\n+\t}\n+\telse if (!prefixcmp(arg, \"--until=\")) {\n+\t\trevs->min_age = approxidate(arg + 8);\n+\t}\n+\telse if (!strcmp(arg, \"--first-parent\")) {\n+\t\trevs->first_parent_only = 1;\n+\t}\n+\telse if (!strcmp(arg, \"-g\") ||\n+\t    !strcmp(arg, \"--walk-reflogs\")) {\n+\t\tinit_reflog_walk(&revs->reflog_info);\n+\t}\n+\telse if (!strcmp(arg, \"--default\")) {\n+\t\tif (argc <= 1)\n+\t\t\treturn error(\"bad --default argument\");\n+\t\trevs->def = argv[1];\n+\t\treturn 2;\n+\t}\n+\telse if (!strcmp(arg, \"--merge\")) {\n+\t\trevs->show_merge = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--topo-order\")) {\n+\t\trevs->lifo = 1;\n+\t\trevs->topo_order = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--date-order\")) {\n+\t\trevs->lifo = 0;\n+\t\trevs->topo_order = 1;\n+\t}\n+\telse if (!prefixcmp(arg, \"--early-output\")) {\n+\t\tint count = 100;\n+\t\tswitch (arg[14]) {\n+\t\t  case '=':\n+\t\t    count = atoi(arg+15);\n+\t\t    /* Fallthrough */\n+\t\t  case 0:\n+\t\t    revs->topo_order = 1;\n+\t\t    revs->early_output = count;\n+\t\t}\n+\t}\n+\telse if (!strcmp(arg, \"--parents\")) {\n+\t\trevs->rewrite_parents = 1;\n+\t\trevs->print_parents = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--dense\")) {\n+\t\trevs->dense = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--sparse\")) {\n+\t\trevs->dense = 0;\n+\t}\n+\telse if (!strcmp(arg, \"--show-all\")) {\n+\t\trevs->show_all = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--remove-empty\")) {\n+\t\trevs->remove_empty_trees = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--no-merges\")) {\n+\t\trevs->no_merges = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--boundary\")) {\n+\t\trevs->boundary = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--left-right\")) {\n+\t\trevs->left_right = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--cherry-pick\")) {\n+\t\trevs->cherry_pick = 1;\n+\t\trevs->limited = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--objects\")) {\n+\t\trevs->tag_objects = 1;\n+\t\trevs->tree_objects = 1;\n+\t\trevs->blob_objects = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--objects-edge\")) {\n+\t\trevs->tag_objects = 1;\n+\t\trevs->tree_objects = 1;\n+\t\trevs->blob_objects = 1;\n+\t\trevs->edge_hint = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--unpacked\")) {\n+\t\trevs->unpacked = 1;\n+\t\tfree(revs->ignore_packed);\n+\t\trevs->ignore_packed = NULL;\n+\t\trevs->num_ignore_packed = 0;\n+\t}\n+\telse if (!prefixcmp(arg, \"--unpacked=\")) {\n+\t\trevs->unpacked = 1;\n+\t\tadd_ignore_packed(revs, arg+11);\n+\t}\n+\telse if (!strcmp(arg, \"-r\")) {\n+\t\trevs->diff = 1;\n+\t\tDIFF_OPT_SET(&revs->diffopt, RECURSIVE);\n+\t}\n+\telse if (!strcmp(arg, \"-t\")) {\n+\t\trevs->diff = 1;\n+\t\tDIFF_OPT_SET(&revs->diffopt, RECURSIVE);\n+\t\tDIFF_OPT_SET(&revs->diffopt, TREE_IN_RECURSIVE);\n+\t}\n+\telse if (!strcmp(arg, \"-m\")) {\n+\t\trevs->ignore_merges = 0;\n+\t}\n+\telse if (!strcmp(arg, \"-c\")) {\n+\t\trevs->diff = 1;\n+\t\trevs->dense_combined_merges = 0;\n+\t\trevs->combine_merges = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--cc\")) {\n+\t\trevs->diff = 1;\n+\t\trevs->dense_combined_merges = 1;\n+\t\trevs->combine_merges = 1;\n+\t}\n+\telse if (!strcmp(arg, \"-v\")) {\n+\t\trevs->verbose_header = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--pretty\")) {\n+\t\trevs->verbose_header = 1;\n+\t\tget_commit_format(arg+8, revs);\n+\t}\n+\telse if (!prefixcmp(arg, \"--pretty=\")) {\n+\t\trevs->verbose_header = 1;\n+\t\tget_commit_format(arg+9, revs);\n+\t}\n+\telse if (!strcmp(arg, \"--graph\")) {\n+\t\trevs->topo_order = 1;\n+\t\trevs->rewrite_parents = 1;\n+\t\trevs->graph = graph_init(revs);\n+\t}\n+\telse if (!strcmp(arg, \"--root\")) {\n+\t\trevs->show_root_diff = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--no-commit-id\")) {\n+\t\trevs->no_commit_id = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--always\")) {\n+\t\trevs->always_show_header = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--no-abbrev\")) {\n+\t\trevs->abbrev = 0;\n+\t}\n+\telse if (!strcmp(arg, \"--abbrev\")) {\n+\t\trevs->abbrev = DEFAULT_ABBREV;\n+\t}\n+\telse if (!prefixcmp(arg, \"--abbrev=\")) {\n+\t\trevs->abbrev = strtoul(arg + 9, NULL, 10);\n+\t\tif (revs->abbrev < MINIMUM_ABBREV)\n+\t\t\trevs->abbrev = MINIMUM_ABBREV;\n+\t\telse if (revs->abbrev > 40)\n+\t\t\trevs->abbrev = 40;\n+\t}\n+\telse if (!strcmp(arg, \"--abbrev-commit\")) {\n+\t\trevs->abbrev_commit = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--full-diff\")) {\n+\t\trevs->diff = 1;\n+\t\trevs->full_diff = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--full-history\")) {\n+\t\trevs->simplify_history = 0;\n+\t}\n+\telse if (!strcmp(arg, \"--relative-date\")) {\n+\t\trevs->date_mode = DATE_RELATIVE;\n+\t}\n+\telse if (!strncmp(arg, \"--date=\", 7)) {\n+\t\trevs->date_mode = parse_date_format(arg + 7);\n+\t}\n+\telse if (!strcmp(arg, \"--log-size\")) {\n+\t\trevs->show_log_size = 1;\n+\t}\n+\t/*\n+\t * Grepping the commit log\n+\t */\n+\telse if (!prefixcmp(arg, \"--author=\")) {\n+\t\tadd_header_grep(revs, \"author\", arg+9);\n+\t}\n+\telse if (!prefixcmp(arg, \"--committer=\")) {\n+\t\tadd_header_grep(revs, \"committer\", arg+12);\n+\t}\n+\telse if (!prefixcmp(arg, \"--grep=\")) {\n+\t\tadd_message_grep(revs, arg+7);\n+\t}\n+\telse if (!strcmp(arg, \"--extended-regexp\") ||\n+\t    !strcmp(arg, \"-E\")) {\n+\t\tif (revs->grep_filter)\n+\t\t\trevs->grep_filter->regflags |= REG_EXTENDED;\n+\t}\n+\telse if (!strcmp(arg, \"--regexp-ignore-case\") ||\n+\t    !strcmp(arg, \"-i\")) {\n+\t\tif (revs->grep_filter)\n+\t\t\trevs->grep_filter->regflags |= REG_ICASE;\n+\t}\n+\telse if (!strcmp(arg, \"--fixed-strings\") ||\n+\t    !strcmp(arg, \"-F\")) {\n+\t\tif (revs->grep_filter)\n+\t\t\trevs->grep_filter->fixed = 1;\n+\t}\n+\telse if (!strcmp(arg, \"--all-match\")) {\n+\t\tif (revs->grep_filter)\n+\t\t\trevs->grep_filter->all_match = 1;\n+\t}\n+\telse if (!prefixcmp(arg, \"--encoding=\")) {\n+\t\targ += 11;\n+\t\tif (strcmp(arg, \"none\"))\n+\t\t\tgit_log_output_encoding = xstrdup(arg);\n+\t\telse\n+\t\t\tgit_log_output_encoding = \"\";\n+\t}\n+\telse if (!strcmp(arg, \"--reverse\")) {\n+\t\trevs->reverse ^= 1;\n+\t}\n+\telse if (!strcmp(arg, \"--children\")) {\n+\t\trevs->children.name = \"children\";\n+\t\trevs->limited = 1;\n+\t} else {\n+\t\tint opts = diff_opt_parse(&revs->diffopt, argv, argc);\n+\t\tif (!opts)\n+\t\t\tunkv[(*unkc)++] = arg;\n+\t\treturn opts;\n+\t}\n+\n+\treturn 1;\n+}\n+\n /*\n  * Parse revision information, filling in the \"rev_info\" structure,\n  * and removing the used arguments from the argument list.\n@@ -983,12 +1253,7 @@ static void add_ignore_packed(struct rev_info *revs, const char *name)\n  */\n int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)\n {\n-\tint i, flags, seen_dashdash, show_merge;\n-\tconst char **unrecognized = argv + 1;\n-\tint left = 1;\n-\tint all_match = 0;\n-\tint regflags = 0;\n-\tint fixed = 0;\n+\tint i, flags, left, seen_dashdash;\n \n \t/* First, search for \"--\" */\n \tseen_dashdash = 0;\n@@ -1004,58 +1269,13 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\tbreak;\n \t}\n \n-\tflags = show_merge = 0;\n-\tfor (i = 1; i < argc; i++) {\n+\t/* Second, deal with arguments and options */\n+\tflags = 0;\n+\tfor (left = i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \t\tif (*arg == '-') {\n \t\t\tint opts;\n-\t\t\tif (!prefixcmp(arg, \"--max-count=\")) {\n-\t\t\t\trevs->max_count = atoi(arg + 12);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!prefixcmp(arg, \"--skip=\")) {\n-\t\t\t\trevs->skip_count = atoi(arg + 7);\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 (!prefixcmp(arg, \"-n\")) {\n-\t\t\t\trevs->max_count = atoi(arg + 2);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!prefixcmp(arg, \"--max-age=\")) {\n-\t\t\t\trevs->max_age = atoi(arg + 10);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!prefixcmp(arg, \"--since=\")) {\n-\t\t\t\trevs->max_age = approxidate(arg + 8);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!prefixcmp(arg, \"--after=\")) {\n-\t\t\t\trevs->max_age = approxidate(arg + 8);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!prefixcmp(arg, \"--min-age=\")) {\n-\t\t\t\trevs->min_age = atoi(arg + 10);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!prefixcmp(arg, \"--before=\")) {\n-\t\t\t\trevs->min_age = approxidate(arg + 9);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!prefixcmp(arg, \"--until=\")) {\n-\t\t\t\trevs->min_age = approxidate(arg + 8);\n-\t\t\t\tcontinue;\n-\t\t\t}\n+\n \t\t\tif (!strcmp(arg, \"--all\")) {\n \t\t\t\thandle_refs(revs, flags, for_each_ref);\n \t\t\t\tcontinue;\n@@ -1072,265 +1292,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\t\t\thandle_refs(revs, flags, for_each_remote_ref);\n \t\t\t\tcontinue;\n \t\t\t}\n-\t\t\tif (!strcmp(arg, \"--first-parent\")) {\n-\t\t\t\trevs->first_parent_only = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n \t\t\tif (!strcmp(arg, \"--reflog\")) {\n \t\t\t\thandle_reflog(revs, flags);\n \t\t\t\tcontinue;\n \t\t\t}\n-\t\t\tif (!strcmp(arg, \"-g\") ||\n-\t\t\t\t\t!strcmp(arg, \"--walk-reflogs\")) {\n-\t\t\t\tinit_reflog_walk(&revs->reflog_info);\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, \"--merge\")) {\n-\t\t\t\tshow_merge = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--topo-order\")) {\n-\t\t\t\trevs->lifo = 1;\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 (!prefixcmp(arg, \"--early-output\")) {\n-\t\t\t\tint count = 100;\n-\t\t\t\tswitch (arg[14]) {\n-\t\t\t\tcase '=':\n-\t\t\t\t\tcount = atoi(arg+15);\n-\t\t\t\t\t/* Fallthrough */\n-\t\t\t\tcase 0:\n-\t\t\t\t\trevs->topo_order = 1;\n-\t\t\t\t\trevs->early_output = count;\n-\t\t\t\t\tcontinue;\n-\t\t\t\t}\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--parents\")) {\n-\t\t\t\trevs->rewrite_parents = 1;\n-\t\t\t\trevs->print_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, \"--show-all\")) {\n-\t\t\t\trevs->show_all = 1;\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, \"--left-right\")) {\n-\t\t\t\trevs->left_right = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--cherry-pick\")) {\n-\t\t\t\trevs->cherry_pick = 1;\n-\t\t\t\trevs->limited = 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\tfree(revs->ignore_packed);\n-\t\t\t\trevs->ignore_packed = NULL;\n-\t\t\t\trevs->num_ignore_packed = 0;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!prefixcmp(arg, \"--unpacked=\")) {\n-\t\t\t\trevs->unpacked = 1;\n-\t\t\t\tadd_ignore_packed(revs, arg+11);\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\tDIFF_OPT_SET(&revs->diffopt, RECURSIVE);\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\tDIFF_OPT_SET(&revs->diffopt, RECURSIVE);\n-\t\t\t\tDIFF_OPT_SET(&revs->diffopt, TREE_IN_RECURSIVE);\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 (!strcmp(arg, \"--pretty\")) {\n-\t\t\t\trevs->verbose_header = 1;\n-\t\t\t\tget_commit_format(arg+8, revs);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!prefixcmp(arg, \"--pretty=\")) {\n-\t\t\t\trevs->verbose_header = 1;\n-\t\t\t\tget_commit_format(arg+9, revs);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--graph\")) {\n-\t\t\t\trevs->topo_order = 1;\n-\t\t\t\trevs->rewrite_parents = 1;\n-\t\t\t\trevs->graph = graph_init(revs);\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 (!prefixcmp(arg, \"--abbrev=\")) {\n-\t\t\t\trevs->abbrev = strtoul(arg + 9, NULL, 10);\n-\t\t\t\tif (revs->abbrev < MINIMUM_ABBREV)\n-\t\t\t\t\trevs->abbrev = MINIMUM_ABBREV;\n-\t\t\t\telse if (revs->abbrev > 40)\n-\t\t\t\t\trevs->abbrev = 40;\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\tif (!strcmp(arg, \"--full-history\")) {\n-\t\t\t\trevs->simplify_history = 0;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--relative-date\")) {\n-\t\t\t\trevs->date_mode = DATE_RELATIVE;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strncmp(arg, \"--date=\", 7)) {\n-\t\t\t\trevs->date_mode = parse_date_format(arg + 7);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--log-size\")) {\n-\t\t\t\trevs->show_log_size = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\n-\t\t\t/*\n-\t\t\t * Grepping the commit log\n-\t\t\t */\n-\t\t\tif (!prefixcmp(arg, \"--author=\")) {\n-\t\t\t\tadd_header_grep(revs, \"author\", arg+9);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!prefixcmp(arg, \"--committer=\")) {\n-\t\t\t\tadd_header_grep(revs, \"committer\", arg+12);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!prefixcmp(arg, \"--grep=\")) {\n-\t\t\t\tadd_message_grep(revs, arg+7);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--extended-regexp\") ||\n-\t\t\t    !strcmp(arg, \"-E\")) {\n-\t\t\t\tregflags |= REG_EXTENDED;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--regexp-ignore-case\") ||\n-\t\t\t    !strcmp(arg, \"-i\")) {\n-\t\t\t\tregflags |= REG_ICASE;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--fixed-strings\") ||\n-\t\t\t    !strcmp(arg, \"-F\")) {\n-\t\t\t\tfixed = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--all-match\")) {\n-\t\t\t\tall_match = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!prefixcmp(arg, \"--encoding=\")) {\n-\t\t\t\targ += 11;\n-\t\t\t\tif (strcmp(arg, \"none\"))\n-\t\t\t\t\tgit_log_output_encoding = xstrdup(arg);\n-\t\t\t\telse\n-\t\t\t\t\tgit_log_output_encoding = \"\";\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tif (!strcmp(arg, \"--reverse\")) {\n-\t\t\t\trevs->reverse ^= 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n \t\t\tif (!strcmp(arg, \"--no-walk\")) {\n \t\t\t\trevs->no_walk = 1;\n \t\t\t\tcontinue;\n@@ -1339,19 +1308,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\t\t\trevs->no_walk = 0;\n \t\t\t\tcontinue;\n \t\t\t}\n-\t\t\tif (!strcmp(arg, \"--children\")) {\n-\t\t\t\trevs->children.name = \"children\";\n-\t\t\t\trevs->limited = 1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n \n-\t\t\topts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);\n+\t\t\topts = handle_revision_opt(revs, argc - i, argv + i, &left, argv);\n \t\t\tif (opts > 0) {\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\tif (opts < 0)\n+\t\t\t\texit(128);\n \t\t\tcontinue;\n \t\t}\n \n@@ -1375,21 +1339,18 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\t}\n \t}\n \n-\tif (revs->grep_filter) {\n-\t\trevs->grep_filter->regflags |= regflags;\n-\t\trevs->grep_filter->fixed = fixed;\n-\t}\n-\n-\tif (show_merge)\n+\tif (revs->def == NULL)\n+\t\trevs->def = def;\n+\tif (revs->show_merge)\n \t\tprepare_show_merge(revs);\n-\tif (def && !revs->pending.nr) {\n+\tif (revs->def && !revs->pending.nr) {\n \t\tunsigned char sha1[20];\n \t\tstruct object *object;\n \t\tunsigned mode;\n-\t\tif (get_sha1_with_mode(def, sha1, &mode))\n-\t\t\tdie(\"bad default revision '%s'\", def);\n-\t\tobject = get_reference(revs, def, sha1, 0);\n-\t\tadd_pending_object_with_mode(revs, object, def, mode);\n+\t\tif (get_sha1_with_mode(revs->def, sha1, &mode))\n+\t\t\tdie(\"bad default revision '%s'\", revs->def);\n+\t\tobject = get_reference(revs, revs->def, sha1, 0);\n+\t\tadd_pending_object_with_mode(revs, object, revs->def, mode);\n \t}\n \n \t/* Did the user ask for any diff output? Run the diff! */\n@@ -1423,7 +1384,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch\n \t\tdie(\"diff_setup_done failed\");\n \n \tif (revs->grep_filter) {\n-\t\trevs->grep_filter->all_match = all_match;\n \t\tcompile_grep_patterns(revs->grep_filter);\n \t}\n \ndiff --git a/revision.h b/revision.h\nindex 5b8c56b..cc80fcd 100644\n--- a/revision.h\n+++ b/revision.h\n@@ -26,6 +26,7 @@ struct rev_info {\n \n \t/* Basic information */\n \tconst char *prefix;\n+\tconst char *def;\n \tvoid *prune_data;\n \tunsigned int early_output;\n \n@@ -66,6 +67,7 @@ struct rev_info {\n \n \t/* Format info */\n \tunsigned int\tshown_one:1,\n+\t\t\tshow_merge:1,\n \t\t\tabbrev_commit:1,\n \t\t\tuse_terminator:1,\n \t\t\tmissing_newline:1;\n@@ -120,6 +122,8 @@ volatile show_early_output_fn_t show_early_output;\n \n extern void init_revisions(struct rev_info *revs, const char *prefix);\n extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);\n+extern int handle_revision_opt(struct rev_info *revs, int argc, const char **argv,\n+\t\t\t       int *unkc, const char **unkv);\n extern int handle_revision_arg(const char *arg, struct rev_info *revs,int flags,int cant_be_filename);\n \n extern int prepare_revision_walk(struct rev_info *revs);\n-- \n1.5.6.2.396.gca539\n"},{"id":"82601","messageId":"1215523175-28436-3-git-send-email-madcoder@debian.org","threadId":"14345","inReplyTo":"1215523175-28436-2-git-send-email-madcoder@debian.org","subject":"[PATCH 2/3] git-blame: migrate to incremental parse-option [1/2]","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-08T13:19:34Z","receivedAt":"2008-07-08T13:19:34Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"This step merely moves the parser to an incremental version, still using\nparse_revisions.\n\nSigned-off-by: Pierre Habouzit <madcoder@debian.org>\n---\n builtin-blame.c |  220 +++++++++++++++++++++++++++++-------------------------\n 1 files changed, 118 insertions(+), 102 deletions(-)\n\ndiff --git a/builtin-blame.c b/builtin-blame.c\nindex cf41511..5e82cd3 100644\n--- a/builtin-blame.c\n+++ b/builtin-blame.c\n@@ -18,24 +18,16 @@\n #include \"cache-tree.h\"\n #include \"path-list.h\"\n #include \"mailmap.h\"\n+#include \"parse-options.h\"\n \n-static char blame_usage[] =\n-\"git-blame [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-w] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [--contents <filename>] [--incremental] [commit] [--] file\\n\"\n-\"  -c                  Use the same output mode as git-annotate (Default: off)\\n\"\n-\"  -b                  Show blank SHA-1 for boundary commits (Default: off)\\n\"\n-\"  -l                  Show long commit SHA1 (Default: off)\\n\"\n-\"  --root              Do not treat root commits as boundaries (Default: off)\\n\"\n-\"  -t                  Show raw timestamp (Default: off)\\n\"\n-\"  -f, --show-name     Show original filename (Default: auto)\\n\"\n-\"  -n, --show-number   Show original linenumber (Default: off)\\n\"\n-\"  -s                  Suppress author name and timestamp (Default: off)\\n\"\n-\"  -p, --porcelain     Show in a format designed for machine consumption\\n\"\n-\"  -w                  Ignore whitespace differences\\n\"\n-\"  -L n,m              Process only line range n,m, counting from 1\\n\"\n-\"  -M, -C              Find line movements within and across files\\n\"\n-\"  --incremental       Show blame entries as we find them, incrementally\\n\"\n-\"  --contents file     Use <file>'s contents as the final image\\n\"\n-\"  -S revs-file        Use revisions from revs-file instead of calling git-rev-list\\n\";\n+static char blame_usage[] = \"git-blame [options] [rev-opts] [rev] [--] file\";\n+\n+static const char *blame_opt_usage[] = {\n+\tblame_usage,\n+\t\"\",\n+\t\"[rev-opts] are documented in git-rev-parse(1)\",\n+\tNULL\n+};\n \n static int longest_file;\n static int longest_author;\n@@ -2219,6 +2211,50 @@ static const char *prepare_initial(struct scoreboard *sb)\n \treturn final_commit_name;\n }\n \n+static int blame_copy_callback(const struct option *option, const char *arg, int unset)\n+{\n+\tint *opt = option->value;\n+\n+\t/*\n+\t * -C enables copy from removed files;\n+\t * -C -C enables copy from existing files, but only\n+\t *       when blaming a new file;\n+\t * -C -C -C enables copy from existing files for\n+\t *          everybody\n+\t */\n+\tif (*opt & PICKAXE_BLAME_COPY_HARDER)\n+\t\t*opt |= PICKAXE_BLAME_COPY_HARDEST;\n+\tif (*opt & PICKAXE_BLAME_COPY)\n+\t\t*opt |= PICKAXE_BLAME_COPY_HARDER;\n+\t*opt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE;\n+\n+\tif (arg)\n+\t\tblame_copy_score = parse_score(arg);\n+\treturn 0;\n+}\n+\n+static int blame_move_callback(const struct option *option, const char *arg, int unset)\n+{\n+\tint *opt = option->value;\n+\n+\t*opt |= PICKAXE_BLAME_MOVE;\n+\n+\tif (arg)\n+\t\tblame_move_score = parse_score(arg);\n+\treturn 0;\n+}\n+\n+static int blame_bottomtop_callback(const struct option *option, const char *arg, int unset)\n+{\n+\tconst char **bottomtop = option->value;\n+\tif (!arg)\n+\t\treturn -1;\n+\tif (*bottomtop)\n+\t\tdie(\"More than one '-L n,m' option given\");\n+\t*bottomtop = arg;\n+\treturn 0;\n+}\n+\n int cmd_blame(int argc, const char **argv, const char *prefix)\n {\n \tstruct rev_info revs;\n@@ -2226,98 +2262,79 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \tstruct scoreboard sb;\n \tstruct origin *o;\n \tstruct blame_entry *ent;\n-\tint i, seen_dashdash, unk, opt;\n+\tint i, seen_dashdash, unk;\n \tlong bottom, top, lno;\n-\tint output_option = 0;\n-\tint show_stats = 0;\n-\tconst char *revs_file = NULL;\n \tconst char *final_commit_name = NULL;\n \tenum object_type type;\n-\tconst char *bottomtop = NULL;\n-\tconst char *contents_from = NULL;\n+\n+\tstatic const char *bottomtop = NULL;\n+\tstatic int output_option = 0, opt = 0;\n+\tstatic int show_stats = 0;\n+\tstatic const char *revs_file = NULL;\n+\tstatic const char *contents_from = NULL;\n+\tstatic const struct option options[] = {\n+\t\tOPT_BOOLEAN(0, \"incremental\", &incremental, \"Show blame entries as we find them, incrementally\"),\n+\t\tOPT_BOOLEAN('b', NULL, &blank_boundary, \"Show blank SHA-1 for boundary commits (Default: off)\"),\n+\t\tOPT_BOOLEAN(0, \"root\", &show_root, \"Do not treat root commits as boundaries (Default: off)\"),\n+\t\tOPT_BOOLEAN(0, \"show-stats\", &show_stats, \"Show work cost statistics\"),\n+\t\tOPT_BIT(0, \"score-debug\", &output_option, \"Show output score for blame entries\", OUTPUT_SHOW_SCORE),\n+\t\tOPT_BIT('f', \"show-name\", &output_option, \"Show original filename (Default: auto)\", OUTPUT_SHOW_NAME),\n+\t\tOPT_BIT('n', \"show-number\", &output_option, \"Show original linenumber (Default: off)\", OUTPUT_SHOW_NUMBER),\n+\t\tOPT_BIT('p', \"porcelain\", &output_option, \"Show in a format designed for machine consumption\", OUTPUT_PORCELAIN),\n+\t\tOPT_BIT('c', NULL, &output_option, \"Use the same output mode as git-annotate (Default: off)\", OUTPUT_ANNOTATE_COMPAT),\n+\t\tOPT_BIT('t', NULL, &output_option, \"Show raw timestamp (Default: off)\", OUTPUT_RAW_TIMESTAMP),\n+\t\tOPT_BIT('l', NULL, &output_option, \"Show long commit SHA1 (Default: off)\", OUTPUT_LONG_OBJECT_NAME),\n+\t\tOPT_BIT('s', NULL, &output_option, \"Suppress author name and timestamp (Default: off)\", OUTPUT_NO_AUTHOR),\n+\t\tOPT_BIT('w', NULL, &xdl_opts, \"Ignore whitespace differences\", XDF_IGNORE_WHITESPACE),\n+\t\tOPT_STRING('S', NULL, &revs_file, \"file\", \"Use revisions from <file> instead of calling git-rev-list\"),\n+\t\tOPT_STRING(0, \"contents\", &contents_from, \"file\", \"Use <file>'s contents as the final image\"),\n+\t\t{ OPTION_CALLBACK, 'C', NULL, &opt, \"score\", \"Find line copies within and across files\", PARSE_OPT_OPTARG, blame_copy_callback },\n+\t\t{ OPTION_CALLBACK, 'M', NULL, &opt, \"score\", \"Find line movements within and across files\", PARSE_OPT_OPTARG, blame_move_callback },\n+\t\tOPT_CALLBACK('L', NULL, &bottomtop, \"n,m\", \"Process only line range n,m, counting from 1\", blame_bottomtop_callback),\n+\t\tOPT_END()\n+\t};\n+\n+\tstruct parse_opt_ctx_t ctx;\n \n \tcmd_is_annotate = !strcmp(argv[0], \"annotate\");\n \n \tgit_config(git_blame_config, NULL);\n+\tinit_revisions(&revs, NULL);\n \tsave_commit_buffer = 0;\n \n-\topt = 0;\n+\tparse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH |\n+\t\t\t    PARSE_OPT_KEEP_ARGV0);\n+\tfor (;;) {\n+\t\tint n;\n+\n+\t\tswitch (parse_options_step(&ctx, options, blame_opt_usage)) {\n+\t\tcase PARSE_OPT_HELP:\n+\t\t\texit(129);\n+\t\tcase PARSE_OPT_DONE:\n+\t\t\tgoto parse_done;\n+\t\t}\n+\n+\t\tif (!strcmp(ctx.argv[0], \"--reverse\")) {\n+\t\t\tctx.argv[0] = \"--children\";\n+\t\t\treverse = 1;\n+\t\t}\n+\t\tn = handle_revision_opt(&revs, ctx.argc, ctx.argv,\n+\t\t\t\t\t&ctx.cpidx, ctx.out);\n+\t\tif (n <= 0) {\n+\t\t\terror(\"unknown option `%s'\", ctx.argv[0]);\n+\t\t\tusage_with_options(blame_opt_usage, options);\n+\t\t}\n+\t\tctx.argv += n;\n+\t\tctx.argc -= n;\n+\t}\n+parse_done:\n+\targc = parse_options_end(&ctx);\n+\n \tseen_dashdash = 0;\n \tfor (unk = i = 1; i < argc; i++) {\n \t\tconst char *arg = argv[i];\n \t\tif (*arg != '-')\n \t\t\tbreak;\n-\t\telse if (!strcmp(\"-b\", arg))\n-\t\t\tblank_boundary = 1;\n-\t\telse if (!strcmp(\"--root\", arg))\n-\t\t\tshow_root = 1;\n-\t\telse if (!strcmp(\"--reverse\", arg)) {\n-\t\t\targv[unk++] = \"--children\";\n-\t\t\treverse = 1;\n-\t\t}\n-\t\telse if (!strcmp(arg, \"--show-stats\"))\n-\t\t\tshow_stats = 1;\n-\t\telse if (!strcmp(\"-c\", arg))\n-\t\t\toutput_option |= OUTPUT_ANNOTATE_COMPAT;\n-\t\telse if (!strcmp(\"-t\", arg))\n-\t\t\toutput_option |= OUTPUT_RAW_TIMESTAMP;\n-\t\telse if (!strcmp(\"-l\", arg))\n-\t\t\toutput_option |= OUTPUT_LONG_OBJECT_NAME;\n-\t\telse if (!strcmp(\"-s\", arg))\n-\t\t\toutput_option |= OUTPUT_NO_AUTHOR;\n-\t\telse if (!strcmp(\"-w\", arg))\n-\t\t\txdl_opts |= XDF_IGNORE_WHITESPACE;\n-\t\telse if (!strcmp(\"-S\", arg) && ++i < argc)\n-\t\t\trevs_file = argv[i];\n-\t\telse if (!prefixcmp(arg, \"-M\")) {\n-\t\t\topt |= PICKAXE_BLAME_MOVE;\n-\t\t\tblame_move_score = parse_score(arg+2);\n-\t\t}\n-\t\telse if (!prefixcmp(arg, \"-C\")) {\n-\t\t\t/*\n-\t\t\t * -C enables copy from removed files;\n-\t\t\t * -C -C enables copy from existing files, but only\n-\t\t\t *       when blaming a new file;\n-\t\t\t * -C -C -C enables copy from existing files for\n-\t\t\t *          everybody\n-\t\t\t */\n-\t\t\tif (opt & PICKAXE_BLAME_COPY_HARDER)\n-\t\t\t\topt |= PICKAXE_BLAME_COPY_HARDEST;\n-\t\t\tif (opt & PICKAXE_BLAME_COPY)\n-\t\t\t\topt |= PICKAXE_BLAME_COPY_HARDER;\n-\t\t\topt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE;\n-\t\t\tblame_copy_score = parse_score(arg+2);\n-\t\t}\n-\t\telse if (!prefixcmp(arg, \"-L\")) {\n-\t\t\tif (!arg[2]) {\n-\t\t\t\tif (++i >= argc)\n-\t\t\t\t\tusage(blame_usage);\n-\t\t\t\targ = argv[i];\n-\t\t\t}\n-\t\t\telse\n-\t\t\t\targ += 2;\n-\t\t\tif (bottomtop)\n-\t\t\t\tdie(\"More than one '-L n,m' option given\");\n-\t\t\tbottomtop = arg;\n-\t\t}\n-\t\telse if (!strcmp(\"--contents\", arg)) {\n-\t\t\tif (++i >= argc)\n-\t\t\t\tusage(blame_usage);\n-\t\t\tcontents_from = argv[i];\n-\t\t}\n-\t\telse if (!strcmp(\"--incremental\", arg))\n-\t\t\tincremental = 1;\n-\t\telse if (!strcmp(\"--score-debug\", arg))\n-\t\t\toutput_option |= OUTPUT_SHOW_SCORE;\n-\t\telse if (!strcmp(\"-f\", arg) ||\n-\t\t\t !strcmp(\"--show-name\", arg))\n-\t\t\toutput_option |= OUTPUT_SHOW_NAME;\n-\t\telse if (!strcmp(\"-n\", arg) ||\n-\t\t\t !strcmp(\"--show-number\", arg))\n-\t\t\toutput_option |= OUTPUT_SHOW_NUMBER;\n-\t\telse if (!strcmp(\"-p\", arg) ||\n-\t\t\t !strcmp(\"--porcelain\", arg))\n-\t\t\toutput_option |= OUTPUT_PORCELAIN;\n \t\telse if (!strcmp(\"--\", arg)) {\n \t\t\tseen_dashdash = 1;\n \t\t\ti++;\n@@ -2364,16 +2381,16 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \tif (seen_dashdash) {\n \t\t/* (1) */\n \t\tif (argc <= i)\n-\t\t\tusage(blame_usage);\n+\t\t\tusage_with_options(blame_opt_usage, options);\n \t\tpath = add_prefix(prefix, argv[i]);\n \t\tif (i + 1 == argc - 1) {\n \t\t\tif (unk != 1)\n-\t\t\t\tusage(blame_usage);\n+\t\t\t\tusage_with_options(blame_opt_usage, options);\n \t\t\targv[unk++] = argv[i + 1];\n \t\t}\n \t\telse if (i + 1 != argc)\n \t\t\t/* garbage at end */\n-\t\t\tusage(blame_usage);\n+\t\t\tusage_with_options(blame_opt_usage, options);\n \t}\n \telse {\n \t\tint j;\n@@ -2383,7 +2400,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \t\tif (seen_dashdash) {\n \t\t\t/* (2) */\n \t\t\tif (seen_dashdash + 1 != argc - 1)\n-\t\t\t\tusage(blame_usage);\n+\t\t\t\tusage_with_options(blame_opt_usage, options);\n \t\t\tpath = add_prefix(prefix, argv[seen_dashdash + 1]);\n \t\t\tfor (j = i; j < seen_dashdash; j++)\n \t\t\t\targv[unk++] = argv[j];\n@@ -2391,7 +2408,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \t\telse {\n \t\t\t/* (3) */\n \t\t\tif (argc <= i)\n-\t\t\t\tusage(blame_usage);\n+\t\t\t\tusage_with_options(blame_opt_usage, options);\n \t\t\tpath = add_prefix(prefix, argv[i]);\n \t\t\tif (i + 1 == argc - 1) {\n \t\t\t\tfinal_commit_name = argv[i + 1];\n@@ -2405,7 +2422,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \t\t\t\t}\n \t\t\t}\n \t\t\telse if (i != argc - 1)\n-\t\t\t\tusage(blame_usage); /* garbage at end */\n+\t\t\t\tusage_with_options(blame_opt_usage, options);\n \n \t\t\tsetup_work_tree();\n \t\t\tif (!has_path_in_work_tree(path))\n@@ -2424,7 +2441,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \targv[unk++] = \"--\"; /* terminate the rev name */\n \targv[unk] = NULL;\n \n-\tinit_revisions(&revs, NULL);\n \tsetup_revisions(unk, argv, &revs, NULL);\n \tmemset(&sb, 0, sizeof(sb));\n \n-- \n1.5.6.2.396.gca539\n"},{"id":"82600","messageId":"1215523175-28436-4-git-send-email-madcoder@debian.org","threadId":"14345","inReplyTo":"1215523175-28436-3-git-send-email-madcoder@debian.org","subject":"[PATCH 3/3] git-blame: migrate to incremental parse-option [2/2]","fromName":"Pierre Habouzit","fromEmail":"madcoder@debian.org","sentAt":"2008-07-08T13:19:35Z","receivedAt":"2008-07-08T13:19:35Z","isPatch":true,"sender":{"key":"madcoder@debian.org","avatar":"https://avatars.githubusercontent.com/u/44708?v=4"},"body":"Now use handle_revision_args instead of parse_revisions, and simplify the\nhandling of old-style arguments a lot thanks to the filtering.\n\nSigned-off-by: Pierre Habouzit <madcoder@debian.org>\n---\n builtin-blame.c |  130 ++++++++++++++++---------------------------------------\n 1 files changed, 38 insertions(+), 92 deletions(-)\n\ndiff --git a/builtin-blame.c b/builtin-blame.c\nindex 5e82cd3..99f5140 100644\n--- a/builtin-blame.c\n+++ b/builtin-blame.c\n@@ -2262,8 +2262,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \tstruct scoreboard sb;\n \tstruct origin *o;\n \tstruct blame_entry *ent;\n-\tint i, seen_dashdash, unk;\n-\tlong bottom, top, lno;\n+\tlong dashdash_pos, bottom, top, lno;\n \tconst char *final_commit_name = NULL;\n \tenum object_type type;\n \n@@ -2301,6 +2300,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \tgit_config(git_blame_config, NULL);\n \tinit_revisions(&revs, NULL);\n \tsave_commit_buffer = 0;\n+\tdashdash_pos = 0;\n \n \tparse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH |\n \t\t\t    PARSE_OPT_KEEP_ARGV0);\n@@ -2311,6 +2311,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \t\tcase PARSE_OPT_HELP:\n \t\t\texit(129);\n \t\tcase PARSE_OPT_DONE:\n+\t\t\tif (ctx.argv[0])\n+\t\t\t\tdashdash_pos = ctx.cpidx;\n \t\t\tgoto parse_done;\n \t\t}\n \n@@ -2330,20 +2332,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n parse_done:\n \targc = parse_options_end(&ctx);\n \n-\tseen_dashdash = 0;\n-\tfor (unk = i = 1; i < argc; i++) {\n-\t\tconst char *arg = argv[i];\n-\t\tif (*arg != '-')\n-\t\t\tbreak;\n-\t\telse if (!strcmp(\"--\", arg)) {\n-\t\t\tseen_dashdash = 1;\n-\t\t\ti++;\n-\t\t\tbreak;\n-\t\t}\n-\t\telse\n-\t\t\targv[unk++] = arg;\n-\t}\n-\n \tif (!blame_move_score)\n \t\tblame_move_score = BLAME_DEFAULT_MOVE_SCORE;\n \tif (!blame_copy_score)\n@@ -2356,92 +2344,50 @@ parse_done:\n \t *\n \t * The remaining are:\n \t *\n-\t * (1) if seen_dashdash, its either\n-\t *     \"-options -- <path>\" or\n-\t *     \"-options -- <path> <rev>\".\n-\t *     but the latter is allowed only if there is no\n-\t *     options that we passed to revision machinery.\n+\t * (1) if dashdash_pos != 0, its either\n+\t *     \"blame [revisions] -- <path>\" or\n+\t *     \"blame -- <path> <rev>\"\n \t *\n-\t * (2) otherwise, we may have \"--\" somewhere later and\n-\t *     might be looking at the first one of multiple 'rev'\n-\t *     parameters (e.g. \" master ^next ^maint -- path\").\n-\t *     See if there is a dashdash first, and give the\n-\t *     arguments before that to revision machinery.\n-\t *     After that there must be one 'path'.\n+\t * (2) otherwise, its one of the two:\n+\t *     \"blame [revisions] <path>\"\n+\t *     \"blame <path> <rev>\"\n \t *\n-\t * (3) otherwise, its one of the three:\n-\t *     \"-options <path> <rev>\"\n-\t *     \"-options <rev> <path>\"\n-\t *     \"-options <path>\"\n-\t *     but again the first one is allowed only if\n-\t *     there is no options that we passed to revision\n-\t *     machinery.\n+\t * Note that we must strip out <path> from the arguments: we do not\n+\t * want the path pruning but we may want \"bottom\" processing.\n \t */\n-\n-\tif (seen_dashdash) {\n-\t\t/* (1) */\n-\t\tif (argc <= i)\n-\t\t\tusage_with_options(blame_opt_usage, options);\n-\t\tpath = add_prefix(prefix, argv[i]);\n-\t\tif (i + 1 == argc - 1) {\n-\t\t\tif (unk != 1)\n+\tif (dashdash_pos) {\n+\t\tswitch (argc - dashdash_pos - 1) {\n+\t\tcase 2: /* (1b) */\n+\t\t\tif (argc != 4)\n \t\t\t\tusage_with_options(blame_opt_usage, options);\n-\t\t\targv[unk++] = argv[i + 1];\n+\t\t\t/* reorder for the new way: <rev> -- <path> */\n+\t\t\targv[1] = argv[3];\n+\t\t\targv[3] = argv[2];\n+\t\t\targv[2] = \"--\";\n+\t\t\t/* FALLTHROUGH */\n+\t\tcase 1: /* (1a) */\n+\t\t\tpath = add_prefix(prefix, argv[--argc]);\n+\t\t\targv[argc] = NULL;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tusage_with_options(blame_opt_usage, options);\n \t\t}\n-\t\telse if (i + 1 != argc)\n-\t\t\t/* garbage at end */\n+\t} else {\n+\t\tif (argc < 2)\n \t\t\tusage_with_options(blame_opt_usage, options);\n-\t}\n-\telse {\n-\t\tint j;\n-\t\tfor (j = i; !seen_dashdash && j < argc; j++)\n-\t\t\tif (!strcmp(argv[j], \"--\"))\n-\t\t\t\tseen_dashdash = j;\n-\t\tif (seen_dashdash) {\n-\t\t\t/* (2) */\n-\t\t\tif (seen_dashdash + 1 != argc - 1)\n-\t\t\t\tusage_with_options(blame_opt_usage, options);\n-\t\t\tpath = add_prefix(prefix, argv[seen_dashdash + 1]);\n-\t\t\tfor (j = i; j < seen_dashdash; j++)\n-\t\t\t\targv[unk++] = argv[j];\n+\t\tpath = add_prefix(prefix, argv[argc - 1]);\n+\t\tif (argc == 3 && !has_path_in_work_tree(path)) { /* (2b) */\n+\t\t\tpath = add_prefix(prefix, argv[1]);\n+\t\t\targv[1] = argv[2];\n \t\t}\n-\t\telse {\n-\t\t\t/* (3) */\n-\t\t\tif (argc <= i)\n-\t\t\t\tusage_with_options(blame_opt_usage, options);\n-\t\t\tpath = add_prefix(prefix, argv[i]);\n-\t\t\tif (i + 1 == argc - 1) {\n-\t\t\t\tfinal_commit_name = argv[i + 1];\n-\n-\t\t\t\t/* if (unk == 1) we could be getting\n-\t\t\t\t * old-style\n-\t\t\t\t */\n-\t\t\t\tif (unk == 1 && !has_path_in_work_tree(path)) {\n-\t\t\t\t\tpath = add_prefix(prefix, argv[i + 1]);\n-\t\t\t\t\tfinal_commit_name = argv[i];\n-\t\t\t\t}\n-\t\t\t}\n-\t\t\telse if (i != argc - 1)\n-\t\t\t\tusage_with_options(blame_opt_usage, options);\n+\t\targv[argc - 1] = \"--\";\n \n-\t\t\tsetup_work_tree();\n-\t\t\tif (!has_path_in_work_tree(path))\n-\t\t\t\tdie(\"cannot stat path %s: %s\",\n-\t\t\t\t    path, strerror(errno));\n-\t\t}\n+\t\tsetup_work_tree();\n+\t\tif (!has_path_in_work_tree(path))\n+\t\t\tdie(\"cannot stat path %s: %s\", path, strerror(errno));\n \t}\n \n-\tif (final_commit_name)\n-\t\targv[unk++] = final_commit_name;\n-\n-\t/*\n-\t * Now we got rev and path.  We do not want the path pruning\n-\t * but we may want \"bottom\" processing.\n-\t */\n-\targv[unk++] = \"--\"; /* terminate the rev name */\n-\targv[unk] = NULL;\n-\n-\tsetup_revisions(unk, argv, &revs, NULL);\n+\tsetup_revisions(argc, argv, &revs, NULL);\n \tmemset(&sb, 0, sizeof(sb));\n \n \tsb.revs = &revs;\n-- \n1.5.6.2.396.gca539\n"},{"id":"82615","messageId":"alpine.LFD.1.10.0807081041310.11076@woody.linux-foundation.org","threadId":"14345","inReplyTo":"1215523175-28436-1-git-send-email-madcoder@debian.org","subject":"Re: [take 2] revision parsing made incremental","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2008-07-08T17:41:47Z","receivedAt":"2008-07-08T17:41:47Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Tue, 8 Jul 2008, Pierre Habouzit wrote:\n> \n> The series passes the testsuite, has no know blanks issues, and is\n> pushed to my public repository.\n\nAck. Looks good to me.\n\n\t\tLinus\n"},{"id":"82643","messageId":"7vk5fwq90o.fsf@gitster.siamese.dyndns.org","threadId":"14345","inReplyTo":"1215523175-28436-1-git-send-email-madcoder@debian.org","subject":"Re: [take 2] revision parsing made incremental","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-07-08T22:57:27Z","receivedAt":"2008-07-08T22:57:27Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Pierre Habouzit <madcoder@debian.org> writes:\n\n> Following Dscho's remarks, I reworked the series to avoid changing\n> setup_revisions semantics for now, and only exposed the part that groks\n> options (and keep pseudo revision arguments out).\n>\n> It indeed makes the series smaller, even if the first patch is quite\n> long to read, and is just enough for simplifying git-blame in a very\n> satisfying way.\n\nAll looks good and the result looks much more readable.\nThanks.\n"}]}