in revision.c [2979:3182]
int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *opt)
{
int i, flags, left, seen_dashdash, revarg_opt;
struct strvec prune_data = STRVEC_INIT;
int seen_end_of_options = 0;
/* First, search for "--" */
if (opt && opt->assume_dashdash) {
seen_dashdash = 1;
} else {
seen_dashdash = 0;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (strcmp(arg, "--"))
continue;
if (opt && opt->free_removed_argv_elements)
free((char *)argv[i]);
argv[i] = NULL;
argc = i;
if (argv[i + 1])
strvec_pushv(&prune_data, argv + i + 1);
seen_dashdash = 1;
break;
}
}
/* Second, deal with arguments and options */
flags = 0;
revarg_opt = opt ? opt->revarg_opt : 0;
if (seen_dashdash)
revarg_opt |= REVARG_CANNOT_BE_FILENAME;
for (left = i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!seen_end_of_options && *arg == '-') {
int opts;
opts = handle_revision_pseudo_opt(
revs, argv + i,
&flags);
if (opts > 0) {
i += opts - 1;
continue;
}
if (!strcmp(arg, "--stdin")) {
if (revs->disable_stdin) {
argv[left++] = arg;
continue;
}
if (revs->read_from_stdin++)
die("--stdin given twice?");
read_revisions_from_stdin(revs, &prune_data);
continue;
}
if (!strcmp(arg, "--end-of-options")) {
seen_end_of_options = 1;
continue;
}
opts = handle_revision_opt(revs, argc - i, argv + i,
&left, argv, opt);
if (opts > 0) {
i += opts - 1;
continue;
}
if (opts < 0)
exit(128);
continue;
}
if (handle_revision_arg(arg, revs, flags, revarg_opt)) {
int j;
if (seen_dashdash || *arg == '^')
die("bad revision '%s'", arg);
/* If we didn't have a "--":
* (1) all filenames must exist;
* (2) all rev-args must not be interpretable
* as a valid filename.
* but the latter we have checked in the main loop.
*/
for (j = i; j < argc; j++)
verify_filename(revs->prefix, argv[j], j == i);
strvec_pushv(&prune_data, argv + i);
break;
}
}
revision_opts_finish(revs);
if (prune_data.nr) {
/*
* If we need to introduce the magic "a lone ':' means no
* pathspec whatsoever", here is the place to do so.
*
* if (prune_data.nr == 1 && !strcmp(prune_data[0], ":")) {
* prune_data.nr = 0;
* prune_data.alloc = 0;
* free(prune_data.path);
* prune_data.path = NULL;
* } else {
* terminate prune_data.alloc with NULL and
* call init_pathspec() to set revs->prune_data here.
* }
*/
parse_pathspec(&revs->prune_data, 0, 0,
revs->prefix, prune_data.v);
}
strvec_clear(&prune_data);
if (!revs->def)
revs->def = opt ? opt->def : NULL;
if (opt && opt->tweak)
opt->tweak(revs);
if (revs->show_merge)
prepare_show_merge(revs);
if (revs->def && !revs->pending.nr && !revs->rev_input_given) {
struct object_id oid;
struct object *object;
struct object_context oc;
if (get_oid_with_context(revs->repo, revs->def, 0, &oid, &oc))
diagnose_missing_default(revs->def);
object = get_reference(revs, revs->def, &oid, 0);
add_pending_object_with_mode(revs, object, revs->def, oc.mode);
object_context_release(&oc);
}
/* Did the user ask for any diff output? Run the diff! */
if (revs->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT)
revs->diff = 1;
/* Pickaxe, diff-filter and rename following need diffs */
if ((revs->diffopt.pickaxe_opts & DIFF_PICKAXE_KINDS_MASK) ||
revs->diffopt.filter ||
revs->diffopt.flags.follow_renames)
revs->diff = 1;
if (revs->diffopt.objfind)
revs->simplify_history = 0;
if (revs->line_level_traverse) {
if (want_ancestry(revs))
revs->limited = 1;
revs->topo_order = 1;
}
if (revs->topo_order && !generation_numbers_enabled(the_repository))
revs->limited = 1;
if (revs->prune_data.nr) {
copy_pathspec(&revs->pruning.pathspec, &revs->prune_data);
/* Can't prune commits with rename following: the paths change.. */
if (!revs->diffopt.flags.follow_renames)
revs->prune = 1;
if (!revs->full_diff)
copy_pathspec(&revs->diffopt.pathspec,
&revs->prune_data);
}
diff_merges_setup_revs(revs);
revs->diffopt.abbrev = revs->abbrev;
diff_setup_done(&revs->diffopt);
if (!is_encoding_utf8(get_log_output_encoding()))
revs->grep_filter.ignore_locale = 1;
compile_grep_patterns(&revs->grep_filter);
if (revs->reflog_info && revs->limited)
die("cannot combine --walk-reflogs with history-limiting options");
if (revs->rewrite_parents && revs->children.name)
die(_("options '%s' and '%s' cannot be used together"), "--parents", "--children");
if (revs->filter.choice && !revs->blob_objects)
die(_("object filtering requires --objects"));
/*
* Limitations on the graph functionality
*/
die_for_incompatible_opt3(!!revs->graph, "--graph",
!!revs->reverse, "--reverse",
!!revs->reflog_info, "--walk-reflogs");
if (revs->no_walk && revs->graph)
die(_("options '%s' and '%s' cannot be used together"), "--no-walk", "--graph");
if (!revs->reflog_info && revs->grep_filter.use_reflog_filter)
die(_("the option '%s' requires '%s'"), "--grep-reflog", "--walk-reflogs");
if (revs->line_level_traverse &&
(revs->diffopt.output_format & ~(DIFF_FORMAT_PATCH | DIFF_FORMAT_NO_OUTPUT)))
die(_("-L does not yet support diff formats besides -p and -s"));
if (revs->expand_tabs_in_log < 0)
revs->expand_tabs_in_log = revs->expand_tabs_in_log_default;
if (!revs->show_notes_given && revs->show_notes_by_default) {
enable_default_display_notes(&revs->notes_opt, &revs->show_notes);
revs->show_notes_given = 1;
}
return left;
}