revisions: split handle_revision_opt() from setup_revisions()

Add two fields to struct rev_info:

 - .def to store --default argument; and
 - .show_merge 1-bit field.

handle_revision_opt() is able to deal with any revision option, and
consumes them, and leaves revision arguments or pseudo arguments
(like --all, --not, ...) in place.

For now setup_revisions() does a pass of handle_revision_opt() again
so that code not using it in a parse-opt parser still work the same.

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:33 +02:00 committed by Junio C Hamano
parent 8bb65883d1
commit 02e542206f
2 changed files with 226 additions and 326 deletions

View File

@ -957,6 +957,212 @@ static void add_ignore_packed(struct rev_info *revs, const char *name)
revs->ignore_packed[num] = NULL;
}
int handle_revision_opt(struct rev_info *revs, int argc, const char **argv,
int *unkc, const char **unkv)
{
const char *arg = argv[0];
/* pseudo revision arguments */
if (!strcmp(arg, "--all") || !strcmp(arg, "--branches") ||
!strcmp(arg, "--tags") || !strcmp(arg, "--remotes") ||
!strcmp(arg, "--reflog") || !strcmp(arg, "--not") ||
!strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk"))
{
unkv[(*unkc)++] = arg;
return 0;
}
if (!prefixcmp(arg, "--max-count=")) {
revs->max_count = atoi(arg + 12);
} else if (!prefixcmp(arg, "--skip=")) {
revs->skip_count = atoi(arg + 7);
} else if ((*arg == '-') && isdigit(arg[1])) {
/* accept -<digit>, like traditional "head" */
revs->max_count = atoi(arg + 1);
} else if (!strcmp(arg, "-n")) {
if (argc <= 1)
return error("-n requires an argument");
revs->max_count = atoi(argv[1]);
return 2;
} else if (!prefixcmp(arg, "-n")) {
revs->max_count = atoi(arg + 2);
} else if (!prefixcmp(arg, "--max-age=")) {
revs->max_age = atoi(arg + 10);
} else if (!prefixcmp(arg, "--since=")) {
revs->max_age = approxidate(arg + 8);
} else if (!prefixcmp(arg, "--after=")) {
revs->max_age = approxidate(arg + 8);
} else if (!prefixcmp(arg, "--min-age=")) {
revs->min_age = atoi(arg + 10);
} else if (!prefixcmp(arg, "--before=")) {
revs->min_age = approxidate(arg + 9);
} else if (!prefixcmp(arg, "--until=")) {
revs->min_age = approxidate(arg + 8);
} else if (!strcmp(arg, "--first-parent")) {
revs->first_parent_only = 1;
} else if (!strcmp(arg, "-g") || !strcmp(arg, "--walk-reflogs")) {
init_reflog_walk(&revs->reflog_info);
} else if (!strcmp(arg, "--default")) {
if (argc <= 1)
return error("bad --default argument");
revs->def = argv[1];
return 2;
} else if (!strcmp(arg, "--merge")) {
revs->show_merge = 1;
} else if (!strcmp(arg, "--topo-order")) {
revs->lifo = 1;
revs->topo_order = 1;
} else if (!strcmp(arg, "--date-order")) {
revs->lifo = 0;
revs->topo_order = 1;
} else if (!prefixcmp(arg, "--early-output")) {
int count = 100;
switch (arg[14]) {
case '=':
count = atoi(arg+15);
/* Fallthrough */
case 0:
revs->topo_order = 1;
revs->early_output = count;
}
} else if (!strcmp(arg, "--parents")) {
revs->rewrite_parents = 1;
revs->print_parents = 1;
} else if (!strcmp(arg, "--dense")) {
revs->dense = 1;
} else if (!strcmp(arg, "--sparse")) {
revs->dense = 0;
} else if (!strcmp(arg, "--show-all")) {
revs->show_all = 1;
} else if (!strcmp(arg, "--remove-empty")) {
revs->remove_empty_trees = 1;
} else if (!strcmp(arg, "--no-merges")) {
revs->no_merges = 1;
} else if (!strcmp(arg, "--boundary")) {
revs->boundary = 1;
} else if (!strcmp(arg, "--left-right")) {
revs->left_right = 1;
} else if (!strcmp(arg, "--cherry-pick")) {
revs->cherry_pick = 1;
revs->limited = 1;
} else if (!strcmp(arg, "--objects")) {
revs->tag_objects = 1;
revs->tree_objects = 1;
revs->blob_objects = 1;
} else if (!strcmp(arg, "--objects-edge")) {
revs->tag_objects = 1;
revs->tree_objects = 1;
revs->blob_objects = 1;
revs->edge_hint = 1;
} else if (!strcmp(arg, "--unpacked")) {
revs->unpacked = 1;
free(revs->ignore_packed);
revs->ignore_packed = NULL;
revs->num_ignore_packed = 0;
} else if (!prefixcmp(arg, "--unpacked=")) {
revs->unpacked = 1;
add_ignore_packed(revs, arg+11);
} else if (!strcmp(arg, "-r")) {
revs->diff = 1;
DIFF_OPT_SET(&revs->diffopt, RECURSIVE);
} else if (!strcmp(arg, "-t")) {
revs->diff = 1;
DIFF_OPT_SET(&revs->diffopt, RECURSIVE);
DIFF_OPT_SET(&revs->diffopt, TREE_IN_RECURSIVE);
} else if (!strcmp(arg, "-m")) {
revs->ignore_merges = 0;
} else if (!strcmp(arg, "-c")) {
revs->diff = 1;
revs->dense_combined_merges = 0;
revs->combine_merges = 1;
} else if (!strcmp(arg, "--cc")) {
revs->diff = 1;
revs->dense_combined_merges = 1;
revs->combine_merges = 1;
} else if (!strcmp(arg, "-v")) {
revs->verbose_header = 1;
} else if (!strcmp(arg, "--pretty")) {
revs->verbose_header = 1;
get_commit_format(arg+8, revs);
} else if (!prefixcmp(arg, "--pretty=")) {
revs->verbose_header = 1;
get_commit_format(arg+9, revs);
} else if (!strcmp(arg, "--graph")) {
revs->topo_order = 1;
revs->rewrite_parents = 1;
revs->graph = graph_init(revs);
} else if (!strcmp(arg, "--root")) {
revs->show_root_diff = 1;
} else if (!strcmp(arg, "--no-commit-id")) {
revs->no_commit_id = 1;
} else if (!strcmp(arg, "--always")) {
revs->always_show_header = 1;
} else if (!strcmp(arg, "--no-abbrev")) {
revs->abbrev = 0;
} else if (!strcmp(arg, "--abbrev")) {
revs->abbrev = DEFAULT_ABBREV;
} else if (!prefixcmp(arg, "--abbrev=")) {
revs->abbrev = strtoul(arg + 9, NULL, 10);
if (revs->abbrev < MINIMUM_ABBREV)
revs->abbrev = MINIMUM_ABBREV;
else if (revs->abbrev > 40)
revs->abbrev = 40;
} else if (!strcmp(arg, "--abbrev-commit")) {
revs->abbrev_commit = 1;
} else if (!strcmp(arg, "--full-diff")) {
revs->diff = 1;
revs->full_diff = 1;
} else if (!strcmp(arg, "--full-history")) {
revs->simplify_history = 0;
} else if (!strcmp(arg, "--relative-date")) {
revs->date_mode = DATE_RELATIVE;
} else if (!strncmp(arg, "--date=", 7)) {
revs->date_mode = parse_date_format(arg + 7);
} else if (!strcmp(arg, "--log-size")) {
revs->show_log_size = 1;
}
/*
* Grepping the commit log
*/
else if (!prefixcmp(arg, "--author=")) {
add_header_grep(revs, "author", arg+9);
} else if (!prefixcmp(arg, "--committer=")) {
add_header_grep(revs, "committer", arg+12);
} else if (!prefixcmp(arg, "--grep=")) {
add_message_grep(revs, arg+7);
} else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) {
if (revs->grep_filter)
revs->grep_filter->regflags |= REG_EXTENDED;
} else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) {
if (revs->grep_filter)
revs->grep_filter->regflags |= REG_ICASE;
} else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) {
if (revs->grep_filter)
revs->grep_filter->fixed = 1;
} else if (!strcmp(arg, "--all-match")) {
if (revs->grep_filter)
revs->grep_filter->all_match = 1;
} else if (!prefixcmp(arg, "--encoding=")) {
arg += 11;
if (strcmp(arg, "none"))
git_log_output_encoding = xstrdup(arg);
else
git_log_output_encoding = "";
} else if (!strcmp(arg, "--reverse")) {
revs->reverse ^= 1;
} else if (!strcmp(arg, "--children")) {
revs->children.name = "children";
revs->limited = 1;
} else {
int opts = diff_opt_parse(&revs->diffopt, argv, argc);
if (!opts)
unkv[(*unkc)++] = arg;
return opts;
}
return 1;
}
/*
* Parse revision information, filling in the "rev_info" structure,
* and removing the used arguments from the argument list.
@ -966,12 +1172,7 @@ static void add_ignore_packed(struct rev_info *revs, const char *name)
*/
int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)
{
int i, flags, seen_dashdash, show_merge;
const char **unrecognized = argv + 1;
int left = 1;
int all_match = 0;
int regflags = 0;
int fixed = 0;
int i, flags, left, seen_dashdash;
/* First, search for "--" */
seen_dashdash = 0;
@ -987,58 +1188,13 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
break;
}
flags = show_merge = 0;
for (i = 1; i < argc; i++) {
/* Second, deal with arguments and options */
flags = 0;
for (left = i = 1; i < argc; i++) {
const char *arg = argv[i];
if (*arg == '-') {
int opts;
if (!prefixcmp(arg, "--max-count=")) {
revs->max_count = atoi(arg + 12);
continue;
}
if (!prefixcmp(arg, "--skip=")) {
revs->skip_count = atoi(arg + 7);
continue;
}
/* accept -<digit>, like traditional "head" */
if ((*arg == '-') && isdigit(arg[1])) {
revs->max_count = atoi(arg + 1);
continue;
}
if (!strcmp(arg, "-n")) {
if (argc <= i + 1)
die("-n requires an argument");
revs->max_count = atoi(argv[++i]);
continue;
}
if (!prefixcmp(arg, "-n")) {
revs->max_count = atoi(arg + 2);
continue;
}
if (!prefixcmp(arg, "--max-age=")) {
revs->max_age = atoi(arg + 10);
continue;
}
if (!prefixcmp(arg, "--since=")) {
revs->max_age = approxidate(arg + 8);
continue;
}
if (!prefixcmp(arg, "--after=")) {
revs->max_age = approxidate(arg + 8);
continue;
}
if (!prefixcmp(arg, "--min-age=")) {
revs->min_age = atoi(arg + 10);
continue;
}
if (!prefixcmp(arg, "--before=")) {
revs->min_age = approxidate(arg + 9);
continue;
}
if (!prefixcmp(arg, "--until=")) {
revs->min_age = approxidate(arg + 8);
continue;
}
if (!strcmp(arg, "--all")) {
handle_refs(revs, flags, for_each_ref);
continue;
@ -1055,265 +1211,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
handle_refs(revs, flags, for_each_remote_ref);
continue;
}
if (!strcmp(arg, "--first-parent")) {
revs->first_parent_only = 1;
continue;
}
if (!strcmp(arg, "--reflog")) {
handle_reflog(revs, flags);
continue;
}
if (!strcmp(arg, "-g") ||
!strcmp(arg, "--walk-reflogs")) {
init_reflog_walk(&revs->reflog_info);
continue;
}
if (!strcmp(arg, "--not")) {
flags ^= UNINTERESTING;
continue;
}
if (!strcmp(arg, "--default")) {
if (++i >= argc)
die("bad --default argument");
def = argv[i];
continue;
}
if (!strcmp(arg, "--merge")) {
show_merge = 1;
continue;
}
if (!strcmp(arg, "--topo-order")) {
revs->lifo = 1;
revs->topo_order = 1;
continue;
}
if (!strcmp(arg, "--date-order")) {
revs->lifo = 0;
revs->topo_order = 1;
continue;
}
if (!prefixcmp(arg, "--early-output")) {
int count = 100;
switch (arg[14]) {
case '=':
count = atoi(arg+15);
/* Fallthrough */
case 0:
revs->topo_order = 1;
revs->early_output = count;
continue;
}
}
if (!strcmp(arg, "--parents")) {
revs->rewrite_parents = 1;
revs->print_parents = 1;
continue;
}
if (!strcmp(arg, "--dense")) {
revs->dense = 1;
continue;
}
if (!strcmp(arg, "--sparse")) {
revs->dense = 0;
continue;
}
if (!strcmp(arg, "--show-all")) {
revs->show_all = 1;
continue;
}
if (!strcmp(arg, "--remove-empty")) {
revs->remove_empty_trees = 1;
continue;
}
if (!strcmp(arg, "--no-merges")) {
revs->no_merges = 1;
continue;
}
if (!strcmp(arg, "--boundary")) {
revs->boundary = 1;
continue;
}
if (!strcmp(arg, "--left-right")) {
revs->left_right = 1;
continue;
}
if (!strcmp(arg, "--cherry-pick")) {
revs->cherry_pick = 1;
revs->limited = 1;
continue;
}
if (!strcmp(arg, "--objects")) {
revs->tag_objects = 1;
revs->tree_objects = 1;
revs->blob_objects = 1;
continue;
}
if (!strcmp(arg, "--objects-edge")) {
revs->tag_objects = 1;
revs->tree_objects = 1;
revs->blob_objects = 1;
revs->edge_hint = 1;
continue;
}
if (!strcmp(arg, "--unpacked")) {
revs->unpacked = 1;
free(revs->ignore_packed);
revs->ignore_packed = NULL;
revs->num_ignore_packed = 0;
continue;
}
if (!prefixcmp(arg, "--unpacked=")) {
revs->unpacked = 1;
add_ignore_packed(revs, arg+11);
continue;
}
if (!strcmp(arg, "-r")) {
revs->diff = 1;
DIFF_OPT_SET(&revs->diffopt, RECURSIVE);
continue;
}
if (!strcmp(arg, "-t")) {
revs->diff = 1;
DIFF_OPT_SET(&revs->diffopt, RECURSIVE);
DIFF_OPT_SET(&revs->diffopt, TREE_IN_RECURSIVE);
continue;
}
if (!strcmp(arg, "-m")) {
revs->ignore_merges = 0;
continue;
}
if (!strcmp(arg, "-c")) {
revs->diff = 1;
revs->dense_combined_merges = 0;
revs->combine_merges = 1;
continue;
}
if (!strcmp(arg, "--cc")) {
revs->diff = 1;
revs->dense_combined_merges = 1;
revs->combine_merges = 1;
continue;
}
if (!strcmp(arg, "-v")) {
revs->verbose_header = 1;
continue;
}
if (!strcmp(arg, "--pretty")) {
revs->verbose_header = 1;
get_commit_format(arg+8, revs);
continue;
}
if (!prefixcmp(arg, "--pretty=")) {
revs->verbose_header = 1;
get_commit_format(arg+9, revs);
continue;
}
if (!strcmp(arg, "--graph")) {
revs->topo_order = 1;
revs->rewrite_parents = 1;
revs->graph = graph_init(revs);
continue;
}
if (!strcmp(arg, "--root")) {
revs->show_root_diff = 1;
continue;
}
if (!strcmp(arg, "--no-commit-id")) {
revs->no_commit_id = 1;
continue;
}
if (!strcmp(arg, "--always")) {
revs->always_show_header = 1;
continue;
}
if (!strcmp(arg, "--no-abbrev")) {
revs->abbrev = 0;
continue;
}
if (!strcmp(arg, "--abbrev")) {
revs->abbrev = DEFAULT_ABBREV;
continue;
}
if (!prefixcmp(arg, "--abbrev=")) {
revs->abbrev = strtoul(arg + 9, NULL, 10);
if (revs->abbrev < MINIMUM_ABBREV)
revs->abbrev = MINIMUM_ABBREV;
else if (revs->abbrev > 40)
revs->abbrev = 40;
continue;
}
if (!strcmp(arg, "--abbrev-commit")) {
revs->abbrev_commit = 1;
continue;
}
if (!strcmp(arg, "--full-diff")) {
revs->diff = 1;
revs->full_diff = 1;
continue;
}
if (!strcmp(arg, "--full-history")) {
revs->simplify_history = 0;
continue;
}
if (!strcmp(arg, "--relative-date")) {
revs->date_mode = DATE_RELATIVE;
continue;
}
if (!strncmp(arg, "--date=", 7)) {
revs->date_mode = parse_date_format(arg + 7);
continue;
}
if (!strcmp(arg, "--log-size")) {
revs->show_log_size = 1;
continue;
}
/*
* Grepping the commit log
*/
if (!prefixcmp(arg, "--author=")) {
add_header_grep(revs, "author", arg+9);
continue;
}
if (!prefixcmp(arg, "--committer=")) {
add_header_grep(revs, "committer", arg+12);
continue;
}
if (!prefixcmp(arg, "--grep=")) {
add_message_grep(revs, arg+7);
continue;
}
if (!strcmp(arg, "--extended-regexp") ||
!strcmp(arg, "-E")) {
regflags |= REG_EXTENDED;
continue;
}
if (!strcmp(arg, "--regexp-ignore-case") ||
!strcmp(arg, "-i")) {
regflags |= REG_ICASE;
continue;
}
if (!strcmp(arg, "--fixed-strings") ||
!strcmp(arg, "-F")) {
fixed = 1;
continue;
}
if (!strcmp(arg, "--all-match")) {
all_match = 1;
continue;
}
if (!prefixcmp(arg, "--encoding=")) {
arg += 11;
if (strcmp(arg, "none"))
git_log_output_encoding = xstrdup(arg);
else
git_log_output_encoding = "";
continue;
}
if (!strcmp(arg, "--reverse")) {
revs->reverse ^= 1;
continue;
}
if (!strcmp(arg, "--no-walk")) {
revs->no_walk = 1;
continue;
@ -1322,19 +1227,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->no_walk = 0;
continue;
}
if (!strcmp(arg, "--children")) {
revs->children.name = "children";
revs->limited = 1;
continue;
}
opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
opts = handle_revision_opt(revs, argc - i, argv + i, &left, argv);
if (opts > 0) {
i += opts - 1;
continue;
}
*unrecognized++ = arg;
left++;
if (opts < 0)
exit(128);
continue;
}
@ -1358,21 +1258,18 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
}
}
if (revs->grep_filter) {
revs->grep_filter->regflags |= regflags;
revs->grep_filter->fixed = fixed;
}
if (show_merge)
if (revs->def == NULL)
revs->def = def;
if (revs->show_merge)
prepare_show_merge(revs);
if (def && !revs->pending.nr) {
if (revs->def && !revs->pending.nr) {
unsigned char sha1[20];
struct object *object;
unsigned mode;
if (get_sha1_with_mode(def, sha1, &mode))
die("bad default revision '%s'", def);
object = get_reference(revs, def, sha1, 0);
add_pending_object_with_mode(revs, object, def, mode);
if (get_sha1_with_mode(revs->def, sha1, &mode))
die("bad default revision '%s'", revs->def);
object = get_reference(revs, revs->def, sha1, 0);
add_pending_object_with_mode(revs, object, revs->def, mode);
}
/* Did the user ask for any diff output? Run the diff! */
@ -1406,7 +1303,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
die("diff_setup_done failed");
if (revs->grep_filter) {
revs->grep_filter->all_match = all_match;
compile_grep_patterns(revs->grep_filter);
}

View File

@ -25,6 +25,7 @@ struct rev_info {
/* Basic information */
const char *prefix;
const char *def;
void *prune_data;
unsigned int early_output;
@ -65,6 +66,7 @@ struct rev_info {
/* Format info */
unsigned int shown_one:1,
show_merge:1,
abbrev_commit:1,
use_terminator:1,
missing_newline:1;
@ -117,6 +119,8 @@ volatile show_early_output_fn_t show_early_output;
extern void init_revisions(struct rev_info *revs, const char *prefix);
extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
extern int handle_revision_opt(struct rev_info *revs, int argc, const char **argv,
int *unkc, const char **unkv);
extern int handle_revision_arg(const char *arg, struct rev_info *revs,int flags,int cant_be_filename);
extern int prepare_revision_walk(struct rev_info *revs);