Besides preparing an empty option table to be added in. The table is also concatenated with diff option table so we don't need diff_opt_parse() anymore. Merging with pseudo-opt table though will not happen until we kill parse_revision_opt(). --abbrev has to be converted right away to override the same one from the diff option parser (which runs first now, if not overriden) Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- Documentation/technical/api-diff.txt | 6 +-- diff.c | 16 ------- diff.h | 1 - revision.c | 64 +++++++++++++++++++++------- revision.h | 1 + 5 files changed, 53 insertions(+), 35 deletions(-) diff --git a/Documentation/technical/api-diff.txt b/Documentation/technical/api-diff.txt index 30fc0e9c93..1e4e6968f4 100644 --- a/Documentation/technical/api-diff.txt +++ b/Documentation/technical/api-diff.txt @@ -22,9 +22,9 @@ Calling sequence sets up the vanilla default. * Fill in the options structure to specify desired output format, rename - detection, etc. `diff_opt_parse()` can be used to parse options given - from the command line in a way consistent with existing git-diff - family of programs. + detection, etc. `parseopts[]` can be used with parse_options() to + parse options from the command line in a way consistent with + existing git-diff family of programs. * Call `diff_setup_done()`; this inspects the options set up so far for internal consistency and make necessary tweaking to it (e.g. if diff --git a/diff.c b/diff.c index 4d3cf83a27..ef0eb2a160 100644 --- a/diff.c +++ b/diff.c @@ -5522,22 +5522,6 @@ static void prep_parse_options(struct diff_options *options) memcpy(options->parseopts, parseopts, sizeof(parseopts)); } -int diff_opt_parse(struct diff_options *options, - const char **av, int ac, const char *prefix) -{ - if (!prefix) - prefix = ""; - - ac = parse_options(ac, av, prefix, options->parseopts, NULL, - PARSE_OPT_KEEP_DASHDASH | - PARSE_OPT_KEEP_UNKNOWN | - PARSE_OPT_NO_INTERNAL_HELP | - PARSE_OPT_ONE_SHOT | - PARSE_OPT_STOP_AT_NON_OPTION); - - return ac; -} - int parse_rename_score(const char **cp_p) { unsigned long num, scale; diff --git a/diff.h b/diff.h index b20cbcc091..c75480a998 100644 --- a/diff.h +++ b/diff.h @@ -351,7 +351,6 @@ int git_diff_ui_config(const char *var, const char *value, void *cb); #define diff_setup(diffopts) repo_diff_setup(the_repository, diffopts) #endif void repo_diff_setup(struct repository *, struct diff_options *); -int diff_opt_parse(struct diff_options *, const char **, int, const char *); void diff_setup_done(struct diff_options *); int git_config_rename(const char *var, const char *value); diff --git a/revision.c b/revision.c index dd22ac5c39..f15aa3e62d 100644 --- a/revision.c +++ b/revision.c @@ -1611,6 +1611,7 @@ static int add_parents_only(struct rev_info *revs, const char *arg_, int flags, } static void make_pseudo_options(struct rev_info *revs); +static void make_rev_options(struct rev_info *revs); void repo_init_revisions(struct repository *r, struct rev_info *revs, @@ -1653,6 +1654,7 @@ void repo_init_revisions(struct repository *r, revs->notes_opt.use_default_notes = -1; make_pseudo_options(revs); + make_rev_options(revs); } static void add_pending_commit_list(struct rev_info *revs, @@ -1953,6 +1955,38 @@ static void add_message_grep(struct rev_info *revs, const char *pattern) add_grep(revs, pattern, GREP_PATTERN_BODY); } +static int rev_opt_abbrev(const struct option *opt, + const char *optarg, int unset) +{ + struct rev_info *revs = opt->value; + + if (unset) { + revs->abbrev = 0; + } else if (!optarg) { + revs->abbrev = DEFAULT_ABBREV; + } else { + const unsigned hexsz = the_hash_algo->hexsz; + + revs->abbrev = strtoul(optarg, NULL, 10); + if (revs->abbrev < MINIMUM_ABBREV) + revs->abbrev = MINIMUM_ABBREV; + else if (revs->abbrev > hexsz) + revs->abbrev = hexsz; + } + return 0; +} + +static void make_rev_options(struct rev_info *revs) +{ + struct option options[] = { + OPT_CALLBACK_F(0, "abbrev", revs, N_("n"), + N_("show the given source prefix instead of \"a/\""), + PARSE_OPT_OPTARG, rev_opt_abbrev), + OPT_END(), + }; + revs->options = parse_options_concat(options, revs->diffopt.parseopts); +} + static int handle_revision_opt(struct rev_info *revs, int argc, const char **argv, int *unkc, const char **unkv, const struct setup_revision_opt* opt) @@ -1960,7 +1994,6 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg const char *arg = argv[0]; const char *optarg; int argcount; - const unsigned hexsz = the_hash_algo->hexsz; /* pseudo revision arguments */ if (!strcmp(arg, "--all") || !strcmp(arg, "--branches") || @@ -1977,6 +2010,18 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg return 1; } + revs->pseudo_flags = NULL; + revs->pseudo_refs = NULL; + argc = parse_options(argc, argv, revs->prefix, + revs->options, NULL, + PARSE_OPT_KEEP_DASHDASH | + PARSE_OPT_KEEP_UNKNOWN | + PARSE_OPT_NO_INTERNAL_HELP | + PARSE_OPT_ONE_SHOT | + PARSE_OPT_STOP_AT_NON_OPTION); + if (argc) + return argc; + if ((argcount = parse_long_opt("max-count", argv, &optarg))) { revs->max_count = atoi(optarg); revs->no_walk = 0; @@ -2243,16 +2288,6 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg 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 (skip_prefix(arg, "--abbrev=", &optarg)) { - revs->abbrev = strtoul(optarg, NULL, 10); - if (revs->abbrev < MINIMUM_ABBREV) - revs->abbrev = MINIMUM_ABBREV; - else if (revs->abbrev > hexsz) - revs->abbrev = hexsz; } else if (!strcmp(arg, "--abbrev-commit")) { revs->abbrev_commit = 1; revs->abbrev_commit_given = 1; @@ -2324,10 +2359,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg BUG("exclude_promisor_objects can only be used when fetch_if_missing is 0"); revs->exclude_promisor_objects = 1; } else { - int opts = diff_opt_parse(&revs->diffopt, argv, argc, revs->prefix); - if (!opts) - unkv[(*unkc)++] = arg; - return opts; + unkv[(*unkc)++] = arg; + return 0; } if (revs->graph && revs->track_linear) die("--show-linear-break and --graph are incompatible"); @@ -2861,6 +2894,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s revs->expand_tabs_in_log = revs->expand_tabs_in_log_default; FREE_AND_NULL(revs->pseudo_options); + FREE_AND_NULL(revs->options); return left; } diff --git a/revision.h b/revision.h index cec5215c04..4e840c8eb1 100644 --- a/revision.h +++ b/revision.h @@ -283,6 +283,7 @@ struct rev_info { struct option *pseudo_options; int *pseudo_flags; struct ref_store *pseudo_refs; + struct option *options; }; int ref_excluded(struct string_list *, const char *path); -- 2.21.0.1141.gd54ac2cb17