diffcore: add a pickaxe option to find a specific blob
Sometimes users are given a hash of an object and they want to identify it further (ex.: Use verify-pack to find the largest blobs, but what are these? or [1]) One might be tempted to extend git-describe to also work with blobs, such that `git describe <blob-id>` gives a description as '<commit-ish>:<path>'. This was implemented at [2]; as seen by the sheer number of responses (>110), it turns out this is tricky to get right. The hard part to get right is picking the correct 'commit-ish' as that could be the commit that (re-)introduced the blob or the blob that removed the blob; the blob could exist in different branches. Junio hinted at a different approach of solving this problem, which this patch implements. Teach the diff machinery another flag for restricting the information to what is shown. For example: $ ./git log --oneline --find-object=v2.0.0:Makefileb2feb64309
Revert the whole "ask curl-config" topic for now47fbfded53
i18n: only extract comments marked with "TRANSLATORS:" we observe that the Makefile as shipped with 2.0 was appeared in v1.9.2-471-g47fbfded53 and in v2.0.0-rc1-5-gb2feb6430b. The reason why these commits both occur prior to v2.0.0 are evil merges that are not found using this new mechanism. [1] https://stackoverflow.com/questions/223678/which-commit-has-this-blob [2] https://public-inbox.org/git/20171028004419.10139-1-sbeller@google.com/ Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
cf63051ada
commit
15af58c1ad
21
diff.c
21
diff.c
@ -4082,6 +4082,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;
|
||||
@ -4487,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 +4754,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)
|
||||
|
Reference in New Issue
Block a user