diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | diff.c | 20 | ||||
-rw-r--r-- | diff.h | 3 | ||||
-rw-r--r-- | diffcore-blobfind.c | 31 | ||||
-rw-r--r-- | diffcore.h | 1 |
5 files changed, 55 insertions, 1 deletions
@@ -775,6 +775,7 @@ LIB_OBJS += date.o LIB_OBJS += decorate.o LIB_OBJS += diffcore-break.o LIB_OBJS += diffcore-delta.o +LIB_OBJS += diffcore-blobfind.o LIB_OBJS += diffcore-order.o LIB_OBJS += diffcore-pickaxe.o LIB_OBJS += diffcore-rename.o @@ -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->blobfind = NULL; /* pathchange left =NULL by default */ options->change = diff_change; @@ -4487,6 +4488,19 @@ static int parse_ws_error_highlight_opt(struct diff_options *opt, const char *ar return 1; } +static int parse_blobfind_opt(struct diff_options *opt, const char *arg) +{ + struct object_id oid; + + if (get_oid_blob(arg, &oid) || sha1_object_info(oid.hash, NULL) != OBJ_BLOB) + return error("object '%s' is not a blob", arg); + + if (!opt->blobfind) + opt->blobfind = xcalloc(1, sizeof(*opt->blobfind)); + oidset_insert(opt->blobfind, &oid); + return 1; +} + int diff_opt_parse(struct diff_options *options, const char **av, int ac, const char *prefix) { @@ -4736,7 +4750,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, "--blobfind=", &arg)) + return parse_blobfind_opt(options, arg); else if ((argcount = parse_long_opt("diff-filter", av, &optarg))) { int offending = parse_diff_filter_opt(optarg, options); if (offending) @@ -5770,6 +5785,9 @@ void diffcore_std(struct diff_options *options) diffcore_skip_stat_unmatch(options); if (!options->found_follow) { /* See try_to_follow_renames() in tree-diff.c */ + + if (options->blobfind) + diffcore_blobfind(options); if (options->break_opt != -1) diffcore_break(options->break_opt); if (options->detect_rename) @@ -7,6 +7,7 @@ #include "tree-walk.h" #include "pathspec.h" #include "object.h" +#include "oidset.h" struct rev_info; struct diff_options; @@ -174,6 +175,8 @@ struct diff_options { enum diff_words_type word_diff; enum diff_submodule_format submodule_format; + struct oidset *blobfind; + /* this is set by diffcore for DIFF_FORMAT_PATCH */ int found_changes; diff --git a/diffcore-blobfind.c b/diffcore-blobfind.c new file mode 100644 index 0000000000..64bf6922b0 --- /dev/null +++ b/diffcore-blobfind.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017 Google Inc. + */ +#include "cache.h" +#include "diff.h" +#include "diffcore.h" + +void diffcore_blobfind(struct diff_options *options) +{ + struct diff_queue_struct *q = &diff_queued_diff; + struct diff_queue_struct outq; + int i; + + if (!options->blobfind) + BUG("blobfind oidset not initialized???"); + + DIFF_QUEUE_CLEAR(&outq); + for (i = 0; i < q->nr; i++) { + struct diff_filepair *p = q->queue[i]; + + if (!DIFF_PAIR_UNMERGED(p) && + ((DIFF_FILE_VALID(p->one) && + oidset_contains(options->blobfind, &p->one->oid)) || + (DIFF_FILE_VALID(p->two) && + oidset_contains(options->blobfind, &p->two->oid)))) + diff_q(&outq, p); + else + diff_free_filepair(p); + } + *q = outq; +} diff --git a/diffcore.h b/diffcore.h index a30da161da..431917672f 100644 --- a/diffcore.h +++ b/diffcore.h @@ -107,6 +107,7 @@ extern struct diff_filepair *diff_queue(struct diff_queue_struct *, struct diff_filespec *); extern void diff_q(struct diff_queue_struct *, struct diff_filepair *); +extern void diffcore_blobfind(struct diff_options *); extern void diffcore_break(int); extern void diffcore_rename(struct diff_options *); extern void diffcore_merge_broken(void); |