Merge branch 'sb/diff-blobfind-pickaxe'

"diff" family of commands learned "--find-object=<object-id>" option
to limit the findings to changes that involve the named object.

* sb/diff-blobfind-pickaxe:
  diff: use HAS_MULTI_BITS instead of counting bits manually
  diff: properly error out when combining multiple pickaxe options
  diffcore: add a pickaxe option to find a specific blob
  diff: introduce DIFF_PICKAXE_KINDS_MASK
  diff: migrate diff_flags.pickaxe_ignore_case to a pickaxe_opts bit
  diff.h: make pickaxe_opts an unsigned bit field
This commit is contained in:
Junio C Hamano
2018-01-23 13:16:37 -08:00
8 changed files with 154 additions and 39 deletions

43
diff.c
View File

@ -4086,6 +4086,7 @@ void diff_setup(struct diff_options *options)
options->interhunkcontext = diff_interhunk_context_default;
options->ws_error_highlight = ws_error_highlight_default;
options->flags.rename_empty = 1;
options->objfind = NULL;
/* pathchange left =NULL by default */
options->change = diff_change;
@ -4110,22 +4111,20 @@ void diff_setup(struct diff_options *options)
void diff_setup_done(struct diff_options *options)
{
int count = 0;
unsigned check_mask = DIFF_FORMAT_NAME |
DIFF_FORMAT_NAME_STATUS |
DIFF_FORMAT_CHECKDIFF |
DIFF_FORMAT_NO_OUTPUT;
if (options->set_default)
options->set_default(options);
if (options->output_format & DIFF_FORMAT_NAME)
count++;
if (options->output_format & DIFF_FORMAT_NAME_STATUS)
count++;
if (options->output_format & DIFF_FORMAT_CHECKDIFF)
count++;
if (options->output_format & DIFF_FORMAT_NO_OUTPUT)
count++;
if (count > 1)
if (HAS_MULTI_BITS(options->output_format & check_mask))
die(_("--name-only, --name-status, --check and -s are mutually exclusive"));
if (HAS_MULTI_BITS(options->pickaxe_opts & DIFF_PICKAXE_KINDS_MASK))
die(_("-G, -S and --find-object are mutually exclusive"));
/*
* Most of the time we can say "there are changes"
* only by checking if there are changed paths, but
@ -4175,7 +4174,7 @@ void diff_setup_done(struct diff_options *options)
/*
* Also pickaxe would not work very well if you do not say recursive
*/
if (options->pickaxe)
if (options->pickaxe_opts & DIFF_PICKAXE_KINDS_MASK)
options->flags.recursive = 1;
/*
* When patches are generated, submodules diffed against the work tree
@ -4489,6 +4488,23 @@ static int parse_ws_error_highlight_opt(struct diff_options *opt, const char *ar
return 1;
}
static int parse_objfind_opt(struct diff_options *opt, const char *arg)
{
struct object_id oid;
if (get_oid(arg, &oid))
return error("unable to resolve '%s'", arg);
if (!opt->objfind)
opt->objfind = xcalloc(1, sizeof(*opt->objfind));
opt->pickaxe_opts |= DIFF_PICKAXE_KIND_OBJFIND;
opt->flags.recursive = 1;
opt->flags.tree_in_recursive = 1;
oidset_insert(opt->objfind, &oid);
return 1;
}
int diff_opt_parse(struct diff_options *options,
const char **av, int ac, const char *prefix)
{
@ -4736,7 +4752,8 @@ int diff_opt_parse(struct diff_options *options,
else if ((argcount = short_opt('O', av, &optarg))) {
options->orderfile = prefix_filename(prefix, optarg);
return argcount;
}
} else if (skip_prefix(arg, "--find-object=", &arg))
return parse_objfind_opt(options, arg);
else if ((argcount = parse_long_opt("diff-filter", av, &optarg))) {
int offending = parse_diff_filter_opt(optarg, options);
if (offending)
@ -5783,7 +5800,7 @@ void diffcore_std(struct diff_options *options)
if (options->break_opt != -1)
diffcore_merge_broken();
}
if (options->pickaxe)
if (options->pickaxe_opts & DIFF_PICKAXE_KINDS_MASK)
diffcore_pickaxe(options);
if (options->orderfile)
diffcore_order(options->orderfile);