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>
This commit is contained in:
Pierre Habouzit 2008-07-08 15:19:34 +02:00 коммит произвёл Junio C Hamano
Родитель 02e542206f
Коммит 5817da0143
1 изменённых файлов: 118 добавлений и 102 удалений

Просмотреть файл

@ -18,24 +18,16 @@
#include "cache-tree.h" #include "cache-tree.h"
#include "path-list.h" #include "path-list.h"
#include "mailmap.h" #include "mailmap.h"
#include "parse-options.h"
static char blame_usage[] = static char blame_usage[] = "git-blame [options] [rev-opts] [rev] [--] file";
"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"
" -c Use the same output mode as git-annotate (Default: off)\n" static const char *blame_opt_usage[] = {
" -b Show blank SHA-1 for boundary commits (Default: off)\n" blame_usage,
" -l Show long commit SHA1 (Default: off)\n" "",
" --root Do not treat root commits as boundaries (Default: off)\n" "[rev-opts] are documented in git-rev-parse(1)",
" -t Show raw timestamp (Default: off)\n" NULL
" -f, --show-name Show original filename (Default: auto)\n" };
" -n, --show-number Show original linenumber (Default: off)\n"
" -s Suppress author name and timestamp (Default: off)\n"
" -p, --porcelain Show in a format designed for machine consumption\n"
" -w Ignore whitespace differences\n"
" -L n,m Process only line range n,m, counting from 1\n"
" -M, -C Find line movements within and across files\n"
" --incremental Show blame entries as we find them, incrementally\n"
" --contents file Use <file>'s contents as the final image\n"
" -S revs-file Use revisions from revs-file instead of calling git-rev-list\n";
static int longest_file; static int longest_file;
static int longest_author; static int longest_author;
@ -2219,61 +2211,10 @@ static const char *prepare_initial(struct scoreboard *sb)
return final_commit_name; return final_commit_name;
} }
int cmd_blame(int argc, const char **argv, const char *prefix) static int blame_copy_callback(const struct option *option, const char *arg, int unset)
{ {
struct rev_info revs; int *opt = option->value;
const char *path;
struct scoreboard sb;
struct origin *o;
struct blame_entry *ent;
int i, seen_dashdash, unk, opt;
long bottom, top, lno;
int output_option = 0;
int show_stats = 0;
const char *revs_file = NULL;
const char *final_commit_name = NULL;
enum object_type type;
const char *bottomtop = NULL;
const char *contents_from = NULL;
cmd_is_annotate = !strcmp(argv[0], "annotate");
git_config(git_blame_config, NULL);
save_commit_buffer = 0;
opt = 0;
seen_dashdash = 0;
for (unk = i = 1; i < argc; i++) {
const char *arg = argv[i];
if (*arg != '-')
break;
else if (!strcmp("-b", arg))
blank_boundary = 1;
else if (!strcmp("--root", arg))
show_root = 1;
else if (!strcmp("--reverse", arg)) {
argv[unk++] = "--children";
reverse = 1;
}
else if (!strcmp(arg, "--show-stats"))
show_stats = 1;
else if (!strcmp("-c", arg))
output_option |= OUTPUT_ANNOTATE_COMPAT;
else if (!strcmp("-t", arg))
output_option |= OUTPUT_RAW_TIMESTAMP;
else if (!strcmp("-l", arg))
output_option |= OUTPUT_LONG_OBJECT_NAME;
else if (!strcmp("-s", arg))
output_option |= OUTPUT_NO_AUTHOR;
else if (!strcmp("-w", arg))
xdl_opts |= XDF_IGNORE_WHITESPACE;
else if (!strcmp("-S", arg) && ++i < argc)
revs_file = argv[i];
else if (!prefixcmp(arg, "-M")) {
opt |= PICKAXE_BLAME_MOVE;
blame_move_score = parse_score(arg+2);
}
else if (!prefixcmp(arg, "-C")) {
/* /*
* -C enables copy from removed files; * -C enables copy from removed files;
* -C -C enables copy from existing files, but only * -C -C enables copy from existing files, but only
@ -2281,43 +2222,119 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
* -C -C -C enables copy from existing files for * -C -C -C enables copy from existing files for
* everybody * everybody
*/ */
if (opt & PICKAXE_BLAME_COPY_HARDER) if (*opt & PICKAXE_BLAME_COPY_HARDER)
opt |= PICKAXE_BLAME_COPY_HARDEST; *opt |= PICKAXE_BLAME_COPY_HARDEST;
if (opt & PICKAXE_BLAME_COPY) if (*opt & PICKAXE_BLAME_COPY)
opt |= PICKAXE_BLAME_COPY_HARDER; *opt |= PICKAXE_BLAME_COPY_HARDER;
opt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE; *opt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE;
blame_copy_score = parse_score(arg+2);
} if (arg)
else if (!prefixcmp(arg, "-L")) { blame_copy_score = parse_score(arg);
if (!arg[2]) { return 0;
if (++i >= argc) }
usage(blame_usage);
arg = argv[i]; static int blame_move_callback(const struct option *option, const char *arg, int unset)
} {
else int *opt = option->value;
arg += 2;
if (bottomtop) *opt |= PICKAXE_BLAME_MOVE;
if (arg)
blame_move_score = parse_score(arg);
return 0;
}
static int blame_bottomtop_callback(const struct option *option, const char *arg, int unset)
{
const char **bottomtop = option->value;
if (!arg)
return -1;
if (*bottomtop)
die("More than one '-L n,m' option given"); die("More than one '-L n,m' option given");
bottomtop = arg; *bottomtop = arg;
return 0;
}
int cmd_blame(int argc, const char **argv, const char *prefix)
{
struct rev_info revs;
const char *path;
struct scoreboard sb;
struct origin *o;
struct blame_entry *ent;
int i, seen_dashdash, unk;
long bottom, top, lno;
const char *final_commit_name = NULL;
enum object_type type;
static const char *bottomtop = NULL;
static int output_option = 0, opt = 0;
static int show_stats = 0;
static const char *revs_file = NULL;
static const char *contents_from = NULL;
static const struct option options[] = {
OPT_BOOLEAN(0, "incremental", &incremental, "Show blame entries as we find them, incrementally"),
OPT_BOOLEAN('b', NULL, &blank_boundary, "Show blank SHA-1 for boundary commits (Default: off)"),
OPT_BOOLEAN(0, "root", &show_root, "Do not treat root commits as boundaries (Default: off)"),
OPT_BOOLEAN(0, "show-stats", &show_stats, "Show work cost statistics"),
OPT_BIT(0, "score-debug", &output_option, "Show output score for blame entries", OUTPUT_SHOW_SCORE),
OPT_BIT('f', "show-name", &output_option, "Show original filename (Default: auto)", OUTPUT_SHOW_NAME),
OPT_BIT('n', "show-number", &output_option, "Show original linenumber (Default: off)", OUTPUT_SHOW_NUMBER),
OPT_BIT('p', "porcelain", &output_option, "Show in a format designed for machine consumption", OUTPUT_PORCELAIN),
OPT_BIT('c', NULL, &output_option, "Use the same output mode as git-annotate (Default: off)", OUTPUT_ANNOTATE_COMPAT),
OPT_BIT('t', NULL, &output_option, "Show raw timestamp (Default: off)", OUTPUT_RAW_TIMESTAMP),
OPT_BIT('l', NULL, &output_option, "Show long commit SHA1 (Default: off)", OUTPUT_LONG_OBJECT_NAME),
OPT_BIT('s', NULL, &output_option, "Suppress author name and timestamp (Default: off)", OUTPUT_NO_AUTHOR),
OPT_BIT('w', NULL, &xdl_opts, "Ignore whitespace differences", XDF_IGNORE_WHITESPACE),
OPT_STRING('S', NULL, &revs_file, "file", "Use revisions from <file> instead of calling git-rev-list"),
OPT_STRING(0, "contents", &contents_from, "file", "Use <file>'s contents as the final image"),
{ OPTION_CALLBACK, 'C', NULL, &opt, "score", "Find line copies within and across files", PARSE_OPT_OPTARG, blame_copy_callback },
{ OPTION_CALLBACK, 'M', NULL, &opt, "score", "Find line movements within and across files", PARSE_OPT_OPTARG, blame_move_callback },
OPT_CALLBACK('L', NULL, &bottomtop, "n,m", "Process only line range n,m, counting from 1", blame_bottomtop_callback),
OPT_END()
};
struct parse_opt_ctx_t ctx;
cmd_is_annotate = !strcmp(argv[0], "annotate");
git_config(git_blame_config, NULL);
init_revisions(&revs, NULL);
save_commit_buffer = 0;
parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH |
PARSE_OPT_KEEP_ARGV0);
for (;;) {
int n;
switch (parse_options_step(&ctx, options, blame_opt_usage)) {
case PARSE_OPT_HELP:
exit(129);
case PARSE_OPT_DONE:
goto parse_done;
} }
else if (!strcmp("--contents", arg)) {
if (++i >= argc) if (!strcmp(ctx.argv[0], "--reverse")) {
usage(blame_usage); ctx.argv[0] = "--children";
contents_from = argv[i]; reverse = 1;
} }
else if (!strcmp("--incremental", arg)) n = handle_revision_opt(&revs, ctx.argc, ctx.argv,
incremental = 1; &ctx.cpidx, ctx.out);
else if (!strcmp("--score-debug", arg)) if (n <= 0) {
output_option |= OUTPUT_SHOW_SCORE; error("unknown option `%s'", ctx.argv[0]);
else if (!strcmp("-f", arg) || usage_with_options(blame_opt_usage, options);
!strcmp("--show-name", arg)) }
output_option |= OUTPUT_SHOW_NAME; ctx.argv += n;
else if (!strcmp("-n", arg) || ctx.argc -= n;
!strcmp("--show-number", arg)) }
output_option |= OUTPUT_SHOW_NUMBER; parse_done:
else if (!strcmp("-p", arg) || argc = parse_options_end(&ctx);
!strcmp("--porcelain", arg))
output_option |= OUTPUT_PORCELAIN; seen_dashdash = 0;
for (unk = i = 1; i < argc; i++) {
const char *arg = argv[i];
if (*arg != '-')
break;
else if (!strcmp("--", arg)) { else if (!strcmp("--", arg)) {
seen_dashdash = 1; seen_dashdash = 1;
i++; i++;
@ -2364,16 +2381,16 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
if (seen_dashdash) { if (seen_dashdash) {
/* (1) */ /* (1) */
if (argc <= i) if (argc <= i)
usage(blame_usage); usage_with_options(blame_opt_usage, options);
path = add_prefix(prefix, argv[i]); path = add_prefix(prefix, argv[i]);
if (i + 1 == argc - 1) { if (i + 1 == argc - 1) {
if (unk != 1) if (unk != 1)
usage(blame_usage); usage_with_options(blame_opt_usage, options);
argv[unk++] = argv[i + 1]; argv[unk++] = argv[i + 1];
} }
else if (i + 1 != argc) else if (i + 1 != argc)
/* garbage at end */ /* garbage at end */
usage(blame_usage); usage_with_options(blame_opt_usage, options);
} }
else { else {
int j; int j;
@ -2383,7 +2400,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
if (seen_dashdash) { if (seen_dashdash) {
/* (2) */ /* (2) */
if (seen_dashdash + 1 != argc - 1) if (seen_dashdash + 1 != argc - 1)
usage(blame_usage); usage_with_options(blame_opt_usage, options);
path = add_prefix(prefix, argv[seen_dashdash + 1]); path = add_prefix(prefix, argv[seen_dashdash + 1]);
for (j = i; j < seen_dashdash; j++) for (j = i; j < seen_dashdash; j++)
argv[unk++] = argv[j]; argv[unk++] = argv[j];
@ -2391,7 +2408,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
else { else {
/* (3) */ /* (3) */
if (argc <= i) if (argc <= i)
usage(blame_usage); usage_with_options(blame_opt_usage, options);
path = add_prefix(prefix, argv[i]); path = add_prefix(prefix, argv[i]);
if (i + 1 == argc - 1) { if (i + 1 == argc - 1) {
final_commit_name = argv[i + 1]; final_commit_name = argv[i + 1];
@ -2405,7 +2422,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
} }
} }
else if (i != argc - 1) else if (i != argc - 1)
usage(blame_usage); /* garbage at end */ usage_with_options(blame_opt_usage, options);
setup_work_tree(); setup_work_tree();
if (!has_path_in_work_tree(path)) if (!has_path_in_work_tree(path))
@ -2424,7 +2441,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
argv[unk++] = "--"; /* terminate the rev name */ argv[unk++] = "--"; /* terminate the rev name */
argv[unk] = NULL; argv[unk] = NULL;
init_revisions(&revs, NULL);
setup_revisions(unk, argv, &revs, NULL); setup_revisions(unk, argv, &revs, NULL);
memset(&sb, 0, sizeof(sb)); memset(&sb, 0, sizeof(sb));