@matheusbsbs / matheus-bagliano / commits / 3f8d520489
Fork 0

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

Now use handle_revision_args instead of parse_revisions, and simplify the handling of old-style arguments a lot thanks to the filtering. 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 3f8d5204896a85d9268c579fc3e31b22b33fb803
1 file changed +38 -92
builtin-blame.c
+38 -92
@@ -2262,8 +2262,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2262 struct scoreboard sb;
2263 struct origin *o;
2264 struct blame_entry *ent;
2265 - int i, seen_dashdash, unk;
2266 - long bottom, top, lno;
2265 + long dashdash_pos, bottom, top, lno;
2266 const char *final_commit_name = NULL;
2267 enum object_type type;
2268
@@ -2301,6 +2300,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2300 git_config(git_blame_config, NULL);
2301 init_revisions(&revs, NULL);
2302 save_commit_buffer = 0;
2303 + dashdash_pos = 0;
2304
2305 parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH |
2306 PARSE_OPT_KEEP_ARGV0);
@@ -2311,6 +2311,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2311 case PARSE_OPT_HELP:
2312 exit(129);
2313 case PARSE_OPT_DONE:
2314 + if (ctx.argv[0])
2315 + dashdash_pos = ctx.cpidx;
2316 goto parse_done;
2317 }
2318
@@ -2330,20 +2332,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2332 parse_done:
2333 argc = parse_options_end(&ctx);
2334
2333 - seen_dashdash = 0;
2334 - for (unk = i = 1; i < argc; i++) {
2335 - const char *arg = argv[i];
2336 - if (*arg != '-')
2337 - break;
2338 - else if (!strcmp("--", arg)) {
2339 - seen_dashdash = 1;
2340 - i++;
2341 - break;
2342 - }
2343 - else
2344 - argv[unk++] = arg;
2345 - }
2346 -
2335 if (!blame_move_score)
2336 blame_move_score = BLAME_DEFAULT_MOVE_SCORE;
2337 if (!blame_copy_score)
@@ -2356,92 +2344,50 @@ parse_done:
2344 *
2345 * The remaining are:
2346 *
2359 - * (1) if seen_dashdash, its either
2360 - * "-options -- <path>" or
2361 - * "-options -- <path> <rev>".
2362 - * but the latter is allowed only if there is no
2363 - * options that we passed to revision machinery.
2347 + * (1) if dashdash_pos != 0, its either
2348 + * "blame [revisions] -- <path>" or
2349 + * "blame -- <path> <rev>"
2350 *
2365 - * (2) otherwise, we may have "--" somewhere later and
2366 - * might be looking at the first one of multiple 'rev'
2367 - * parameters (e.g. " master ^next ^maint -- path").
2368 - * See if there is a dashdash first, and give the
2369 - * arguments before that to revision machinery.
2370 - * After that there must be one 'path'.
2351 + * (2) otherwise, its one of the two:
2352 + * "blame [revisions] <path>"
2353 + * "blame <path> <rev>"
2354 *
2372 - * (3) otherwise, its one of the three:
2373 - * "-options <path> <rev>"
2374 - * "-options <rev> <path>"
2375 - * "-options <path>"
2376 - * but again the first one is allowed only if
2377 - * there is no options that we passed to revision
2378 - * machinery.
2355 + * Note that we must strip out <path> from the arguments: we do not
2356 + * want the path pruning but we may want "bottom" processing.
2357 */
2380 -
2381 - if (seen_dashdash) {
2382 - /* (1) */
2383 - if (argc <= i)
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)
2358 + if (dashdash_pos) {
2359 + switch (argc - dashdash_pos - 1) {
2360 + case 2: /* (1b) */
2361 + if (argc != 4)
2362 usage_with_options(blame_opt_usage, options);
2389 - argv[unk++] = argv[i + 1];
2363 + /* reorder for the new way: <rev> -- <path> */
2364 + argv[1] = argv[3];
2365 + argv[3] = argv[2];
2366 + argv[2] = "--";
2367 + /* FALLTHROUGH */
2368 + case 1: /* (1a) */
2369 + path = add_prefix(prefix, argv[--argc]);
2370 + argv[argc] = NULL;
2371 + break;
2372 + default:
2373 + usage_with_options(blame_opt_usage, options);
2374 }
2391 - else if (i + 1 != argc)
2392 - /* garbage at end */
2375 + } else {
2376 + if (argc < 2)
2377 usage_with_options(blame_opt_usage, options);
2394 - }
2395 - else {
2396 - int j;
2397 - for (j = i; !seen_dashdash && j < argc; j++)
2398 - if (!strcmp(argv[j], "--"))
2399 - seen_dashdash = j;
2400 - if (seen_dashdash) {
2401 - /* (2) */
2402 - if (seen_dashdash + 1 != argc - 1)
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];
2378 + path = add_prefix(prefix, argv[argc - 1]);
2379 + if (argc == 3 && !has_path_in_work_tree(path)) { /* (2b) */
2380 + path = add_prefix(prefix, argv[1]);
2381 + argv[1] = argv[2];
2382 }
2408 - else {
2409 - /* (3) */
2410 - if (argc <= i)
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];
2415 -
2416 - /* if (unk == 1) we could be getting
2417 - * old-style
2418 - */
2419 - if (unk == 1 && !has_path_in_work_tree(path)) {
2420 - path = add_prefix(prefix, argv[i + 1]);
2421 - final_commit_name = argv[i];
2422 - }
2423 - }
2424 - else if (i != argc - 1)
2425 - usage_with_options(blame_opt_usage, options);
2383 + argv[argc - 1] = "--";
2384
2427 - setup_work_tree();
2428 - if (!has_path_in_work_tree(path))
2429 - die("cannot stat path %s: %s",
2430 - path, strerror(errno));
2431 - }
2385 + setup_work_tree();
2386 + if (!has_path_in_work_tree(path))
2387 + die("cannot stat path %s: %s", path, strerror(errno));
2388 }
2389
2434 - if (final_commit_name)
2435 - argv[unk++] = final_commit_name;
2436 -
2437 - /*
2438 - * Now we got rev and path. We do not want the path pruning
2439 - * but we may want "bottom" processing.
2440 - */
2441 - argv[unk++] = "--"; /* terminate the rev name */
2442 - argv[unk] = NULL;
2443 -
2444 - setup_revisions(unk, argv, &revs, NULL);
2390 + setup_revisions(argc, argv, &revs, NULL);
2391 memset(&sb, 0, sizeof(sb));
2392
2393 sb.revs = &revs;