@matheusbsbs / matheus-bagliano / commits / 5817da0143
Fork 0

git-blame: migrate to incremental parse-option [1/2]

This step merely moves the parser to an incremental version, still using parse_revisions. Signed-off-by: Pierre Habouzit <madcoder@debian.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Pierre Habouzit committed Jul 8, 2008 at 15:19 UTC 5817da01434a24e693ea4d5ba6680d488f5f543f
1 file changed +118 -102
builtin-blame.c
+118 -102
@@ -18,24 +18,16 @@
18 #include "cache-tree.h"
19 #include "path-list.h"
20 #include "mailmap.h"
21 +#include "parse-options.h"
22
22 -static char blame_usage[] =
23 -"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"
24 -" -c Use the same output mode as git-annotate (Default: off)\n"
25 -" -b Show blank SHA-1 for boundary commits (Default: off)\n"
26 -" -l Show long commit SHA1 (Default: off)\n"
27 -" --root Do not treat root commits as boundaries (Default: off)\n"
28 -" -t Show raw timestamp (Default: off)\n"
29 -" -f, --show-name Show original filename (Default: auto)\n"
30 -" -n, --show-number Show original linenumber (Default: off)\n"
31 -" -s Suppress author name and timestamp (Default: off)\n"
32 -" -p, --porcelain Show in a format designed for machine consumption\n"
33 -" -w Ignore whitespace differences\n"
34 -" -L n,m Process only line range n,m, counting from 1\n"
35 -" -M, -C Find line movements within and across files\n"
36 -" --incremental Show blame entries as we find them, incrementally\n"
37 -" --contents file Use <file>'s contents as the final image\n"
38 -" -S revs-file Use revisions from revs-file instead of calling git-rev-list\n";
23 +static char blame_usage[] = "git-blame [options] [rev-opts] [rev] [--] file";
24 +
25 +static const char *blame_opt_usage[] = {
26 + blame_usage,
27 + "",
28 + "[rev-opts] are documented in git-rev-parse(1)",
29 + NULL
30 +};
31
32 static int longest_file;
33 static int longest_author;
@@ -2219,6 +2211,50 @@ static const char *prepare_initial(struct scoreboard *sb)
2211 return final_commit_name;
2212 }
2213
2214 +static int blame_copy_callback(const struct option *option, const char *arg, int unset)
2215 +{
2216 + int *opt = option->value;
2217 +
2218 + /*
2219 + * -C enables copy from removed files;
2220 + * -C -C enables copy from existing files, but only
2221 + * when blaming a new file;
2222 + * -C -C -C enables copy from existing files for
2223 + * everybody
2224 + */
2225 + if (*opt & PICKAXE_BLAME_COPY_HARDER)
2226 + *opt |= PICKAXE_BLAME_COPY_HARDEST;
2227 + if (*opt & PICKAXE_BLAME_COPY)
2228 + *opt |= PICKAXE_BLAME_COPY_HARDER;
2229 + *opt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE;
2230 +
2231 + if (arg)
2232 + blame_copy_score = parse_score(arg);
2233 + return 0;
2234 +}
2235 +
2236 +static int blame_move_callback(const struct option *option, const char *arg, int unset)
2237 +{
2238 + int *opt = option->value;
2239 +
2240 + *opt |= PICKAXE_BLAME_MOVE;
2241 +
2242 + if (arg)
2243 + blame_move_score = parse_score(arg);
2244 + return 0;
2245 +}
2246 +
2247 +static int blame_bottomtop_callback(const struct option *option, const char *arg, int unset)
2248 +{
2249 + const char **bottomtop = option->value;
2250 + if (!arg)
2251 + return -1;
2252 + if (*bottomtop)
2253 + die("More than one '-L n,m' option given");
2254 + *bottomtop = arg;
2255 + return 0;
2256 +}
2257 +
2258 int cmd_blame(int argc, const char **argv, const char *prefix)
2259 {
2260 struct rev_info revs;
@@ -2226,98 +2262,79 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2262 struct scoreboard sb;
2263 struct origin *o;
2264 struct blame_entry *ent;
2229 - int i, seen_dashdash, unk, opt;
2265 + int i, seen_dashdash, unk;
2266 long bottom, top, lno;
2231 - int output_option = 0;
2232 - int show_stats = 0;
2233 - const char *revs_file = NULL;
2267 const char *final_commit_name = NULL;
2268 enum object_type type;
2236 - const char *bottomtop = NULL;
2237 - const char *contents_from = NULL;
2269 +
2270 + static const char *bottomtop = NULL;
2271 + static int output_option = 0, opt = 0;
2272 + static int show_stats = 0;
2273 + static const char *revs_file = NULL;
2274 + static const char *contents_from = NULL;
2275 + static const struct option options[] = {
2276 + OPT_BOOLEAN(0, "incremental", &incremental, "Show blame entries as we find them, incrementally"),
2277 + OPT_BOOLEAN('b', NULL, &blank_boundary, "Show blank SHA-1 for boundary commits (Default: off)"),
2278 + OPT_BOOLEAN(0, "root", &show_root, "Do not treat root commits as boundaries (Default: off)"),
2279 + OPT_BOOLEAN(0, "show-stats", &show_stats, "Show work cost statistics"),
2280 + OPT_BIT(0, "score-debug", &output_option, "Show output score for blame entries", OUTPUT_SHOW_SCORE),
2281 + OPT_BIT('f', "show-name", &output_option, "Show original filename (Default: auto)", OUTPUT_SHOW_NAME),
2282 + OPT_BIT('n', "show-number", &output_option, "Show original linenumber (Default: off)", OUTPUT_SHOW_NUMBER),
2283 + OPT_BIT('p', "porcelain", &output_option, "Show in a format designed for machine consumption", OUTPUT_PORCELAIN),
2284 + OPT_BIT('c', NULL, &output_option, "Use the same output mode as git-annotate (Default: off)", OUTPUT_ANNOTATE_COMPAT),
2285 + OPT_BIT('t', NULL, &output_option, "Show raw timestamp (Default: off)", OUTPUT_RAW_TIMESTAMP),
2286 + OPT_BIT('l', NULL, &output_option, "Show long commit SHA1 (Default: off)", OUTPUT_LONG_OBJECT_NAME),
2287 + OPT_BIT('s', NULL, &output_option, "Suppress author name and timestamp (Default: off)", OUTPUT_NO_AUTHOR),
2288 + OPT_BIT('w', NULL, &xdl_opts, "Ignore whitespace differences", XDF_IGNORE_WHITESPACE),
2289 + OPT_STRING('S', NULL, &revs_file, "file", "Use revisions from <file> instead of calling git-rev-list"),
2290 + OPT_STRING(0, "contents", &contents_from, "file", "Use <file>'s contents as the final image"),
2291 + { OPTION_CALLBACK, 'C', NULL, &opt, "score", "Find line copies within and across files", PARSE_OPT_OPTARG, blame_copy_callback },
2292 + { OPTION_CALLBACK, 'M', NULL, &opt, "score", "Find line movements within and across files", PARSE_OPT_OPTARG, blame_move_callback },
2293 + OPT_CALLBACK('L', NULL, &bottomtop, "n,m", "Process only line range n,m, counting from 1", blame_bottomtop_callback),
2294 + OPT_END()
2295 + };
2296 +
2297 + struct parse_opt_ctx_t ctx;
2298
2299 cmd_is_annotate = !strcmp(argv[0], "annotate");
2300
2301 git_config(git_blame_config, NULL);
2302 + init_revisions(&revs, NULL);
2303 save_commit_buffer = 0;
2304
2244 - opt = 0;
2305 + parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH |
2306 + PARSE_OPT_KEEP_ARGV0);
2307 + for (;;) {
2308 + int n;
2309 +
2310 + switch (parse_options_step(&ctx, options, blame_opt_usage)) {
2311 + case PARSE_OPT_HELP:
2312 + exit(129);
2313 + case PARSE_OPT_DONE:
2314 + goto parse_done;
2315 + }
2316 +
2317 + if (!strcmp(ctx.argv[0], "--reverse")) {
2318 + ctx.argv[0] = "--children";
2319 + reverse = 1;
2320 + }
2321 + n = handle_revision_opt(&revs, ctx.argc, ctx.argv,
2322 + &ctx.cpidx, ctx.out);
2323 + if (n <= 0) {
2324 + error("unknown option `%s'", ctx.argv[0]);
2325 + usage_with_options(blame_opt_usage, options);
2326 + }
2327 + ctx.argv += n;
2328 + ctx.argc -= n;
2329 + }
2330 +parse_done:
2331 + argc = parse_options_end(&ctx);
2332 +
2333 seen_dashdash = 0;
2334 for (unk = i = 1; i < argc; i++) {
2335 const char *arg = argv[i];
2336 if (*arg != '-')
2337 break;
2250 - else if (!strcmp("-b", arg))
2251 - blank_boundary = 1;
2252 - else if (!strcmp("--root", arg))
2253 - show_root = 1;
2254 - else if (!strcmp("--reverse", arg)) {
2255 - argv[unk++] = "--children";
2256 - reverse = 1;
2257 - }
2258 - else if (!strcmp(arg, "--show-stats"))
2259 - show_stats = 1;
2260 - else if (!strcmp("-c", arg))
2261 - output_option |= OUTPUT_ANNOTATE_COMPAT;
2262 - else if (!strcmp("-t", arg))
2263 - output_option |= OUTPUT_RAW_TIMESTAMP;
2264 - else if (!strcmp("-l", arg))
2265 - output_option |= OUTPUT_LONG_OBJECT_NAME;
2266 - else if (!strcmp("-s", arg))
2267 - output_option |= OUTPUT_NO_AUTHOR;
2268 - else if (!strcmp("-w", arg))
2269 - xdl_opts |= XDF_IGNORE_WHITESPACE;
2270 - else if (!strcmp("-S", arg) && ++i < argc)
2271 - revs_file = argv[i];
2272 - else if (!prefixcmp(arg, "-M")) {
2273 - opt |= PICKAXE_BLAME_MOVE;
2274 - blame_move_score = parse_score(arg+2);
2275 - }
2276 - else if (!prefixcmp(arg, "-C")) {
2277 - /*
2278 - * -C enables copy from removed files;
2279 - * -C -C enables copy from existing files, but only
2280 - * when blaming a new file;
2281 - * -C -C -C enables copy from existing files for
2282 - * everybody
2283 - */
2284 - if (opt & PICKAXE_BLAME_COPY_HARDER)
2285 - opt |= PICKAXE_BLAME_COPY_HARDEST;
2286 - if (opt & PICKAXE_BLAME_COPY)
2287 - opt |= PICKAXE_BLAME_COPY_HARDER;
2288 - opt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE;
2289 - blame_copy_score = parse_score(arg+2);
2290 - }
2291 - else if (!prefixcmp(arg, "-L")) {
2292 - if (!arg[2]) {
2293 - if (++i >= argc)
2294 - usage(blame_usage);
2295 - arg = argv[i];
2296 - }
2297 - else
2298 - arg += 2;
2299 - if (bottomtop)
2300 - die("More than one '-L n,m' option given");
2301 - bottomtop = arg;
2302 - }
2303 - else if (!strcmp("--contents", arg)) {
2304 - if (++i >= argc)
2305 - usage(blame_usage);
2306 - contents_from = argv[i];
2307 - }
2308 - else if (!strcmp("--incremental", arg))
2309 - incremental = 1;
2310 - else if (!strcmp("--score-debug", arg))
2311 - output_option |= OUTPUT_SHOW_SCORE;
2312 - else if (!strcmp("-f", arg) ||
2313 - !strcmp("--show-name", arg))
2314 - output_option |= OUTPUT_SHOW_NAME;
2315 - else if (!strcmp("-n", arg) ||
2316 - !strcmp("--show-number", arg))
2317 - output_option |= OUTPUT_SHOW_NUMBER;
2318 - else if (!strcmp("-p", arg) ||
2319 - !strcmp("--porcelain", arg))
2320 - output_option |= OUTPUT_PORCELAIN;
2338 else if (!strcmp("--", arg)) {
2339 seen_dashdash = 1;
2340 i++;
@@ -2364,16 +2381,16 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2381 if (seen_dashdash) {
2382 /* (1) */
2383 if (argc <= i)
2367 - usage(blame_usage);
2384 + usage_with_options(blame_opt_usage, options);
2385 path = add_prefix(prefix, argv[i]);
2386 if (i + 1 == argc - 1) {
2387 if (unk != 1)
2371 - usage(blame_usage);
2388 + usage_with_options(blame_opt_usage, options);
2389 argv[unk++] = argv[i + 1];
2390 }
2391 else if (i + 1 != argc)
2392 /* garbage at end */
2376 - usage(blame_usage);
2393 + usage_with_options(blame_opt_usage, options);
2394 }
2395 else {
2396 int j;
@@ -2383,7 +2400,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2400 if (seen_dashdash) {
2401 /* (2) */
2402 if (seen_dashdash + 1 != argc - 1)
2386 - usage(blame_usage);
2403 + usage_with_options(blame_opt_usage, options);
2404 path = add_prefix(prefix, argv[seen_dashdash + 1]);
2405 for (j = i; j < seen_dashdash; j++)
2406 argv[unk++] = argv[j];
@@ -2391,7 +2408,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2408 else {
2409 /* (3) */
2410 if (argc <= i)
2394 - usage(blame_usage);
2411 + usage_with_options(blame_opt_usage, options);
2412 path = add_prefix(prefix, argv[i]);
2413 if (i + 1 == argc - 1) {
2414 final_commit_name = argv[i + 1];
@@ -2405,7 +2422,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2422 }
2423 }
2424 else if (i != argc - 1)
2408 - usage(blame_usage); /* garbage at end */
2425 + usage_with_options(blame_opt_usage, options);
2426
2427 setup_work_tree();
2428 if (!has_path_in_work_tree(path))
@@ -2424,7 +2441,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2441 argv[unk++] = "--"; /* terminate the rev name */
2442 argv[unk] = NULL;
2443
2427 - init_revisions(&revs, NULL);
2444 setup_revisions(unk, argv, &revs, NULL);
2445 memset(&sb, 0, sizeof(sb));
2446