Merge branch 'sb/diff-blobfind-pickaxe'
authorJunio C Hamano <gitster@pobox.com>
Tue, 23 Jan 2018 21:16:37 +0000 (13:16 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 23 Jan 2018 21:16:37 +0000 (13:16 -0800)
"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

1  2 
Documentation/diff-options.txt
builtin/log.c
diff.c
diff.h
revision.c
index 743af97b06153813820264bb6cf9085f50b6696f,f9cf85db05058983e8bddf5e8766a1e81c50a6d9..c330c01ff096c9f2e66cbbea2557b6429b90e81a
@@@ -80,16 -80,6 +80,16 @@@ endif::git-format-patch[
  --histogram::
        Generate a diff using the "histogram diff" algorithm.
  
 +--anchored=<text>::
 +      Generate a diff using the "anchored diff" algorithm.
 ++
 +This option may be specified more than once.
 ++
 +If a line exists in both the source and destination, exists only once,
 +and starts with this text, this algorithm attempts to prevent it from
 +appearing as a deletion or addition in the output. It uses the "patience
 +diff" algorithm internally.
 +
  --diff-algorithm={patience|minimal|histogram|myers}::
        Choose a diff algorithm. The variants are as follows:
  +
@@@ -469,12 -459,6 +469,12 @@@ ifndef::git-format-patch[
  +
  Also, these upper-case letters can be downcased to exclude.  E.g.
  `--diff-filter=ad` excludes added and deleted paths.
 ++
 +Note that not all diffs can feature all types. For instance, diffs
 +from the index to the working tree can never have Added entries
 +(because the set of paths included in the diff is limited by what is in
 +the index).  Similarly, copied and renamed entries cannot appear if
 +detection for those types is disabled.
  
  -S<string>::
        Look for differences that change the number of occurrences of
@@@ -508,6 -492,15 +508,15 @@@ occurrences of that string did not chan
  See the 'pickaxe' entry in linkgit:gitdiffcore[7] for more
  information.
  
+ --find-object=<object-id>::
+       Look for differences that change the number of occurrences of
+       the specified object. Similar to `-S`, just the argument is different
+       in that it doesn't search for a specific string but for a specific
+       object id.
+ +
+ The object can be a blob or a submodule commit. It implies the `-t` option in
+ `git-log` to also find trees.
  --pickaxe-all::
        When `-S` or `-G` finds a change, show all the changes in that
        changeset, not just the files that contain the change
  --pickaxe-regex::
        Treat the <string> given to `-S` as an extended POSIX regular
        expression to match.
  endif::git-format-patch[]
  
  -O<orderfile>::
@@@ -573,9 -567,6 +583,9 @@@ endif::git-format-patch[
  --text::
        Treat all files as text.
  
 +--ignore-cr-at-eol::
 +      Ignore carrige-return at the end of line when doing a comparison.
 +
  --ignore-space-at-eol::
        Ignore changes in whitespace at EOL.
  
diff --combined builtin/log.c
index 14fdf39165d20602ad8b682b55660ec2466c1d20,bd6f2d1efb9b87f00dd782651d713d4982d5239e..46b4ca13e5c11ff43c15d80e618914e671ff17a0
@@@ -142,19 -142,11 +142,19 @@@ static void cmd_log_init_finish(int arg
        struct userformat_want w;
        int quiet = 0, source = 0, mailmap = 0;
        static struct line_opt_callback_data line_cb = {NULL, NULL, STRING_LIST_INIT_DUP};
 +      static struct string_list decorate_refs_exclude = STRING_LIST_INIT_NODUP;
 +      static struct string_list decorate_refs_include = STRING_LIST_INIT_NODUP;
 +      struct decoration_filter decoration_filter = {&decorate_refs_include,
 +                                                    &decorate_refs_exclude};
  
        const struct option builtin_log_options[] = {
                OPT__QUIET(&quiet, N_("suppress diff output")),
                OPT_BOOL(0, "source", &source, N_("show source")),
                OPT_BOOL(0, "use-mailmap", &mailmap, N_("Use mail map file")),
 +              OPT_STRING_LIST(0, "decorate-refs", &decorate_refs_include,
 +                              N_("pattern"), N_("only decorate refs that match <pattern>")),
 +              OPT_STRING_LIST(0, "decorate-refs-exclude", &decorate_refs_exclude,
 +                              N_("pattern"), N_("do not decorate refs that match <pattern>")),
                { OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"),
                  PARSE_OPT_OPTARG, decorate_callback},
                OPT_CALLBACK('L', NULL, &line_cb, "n,m:file",
        if (rev->show_notes)
                init_display_notes(&rev->notes_opt);
  
-       if (rev->diffopt.pickaxe || rev->diffopt.filter ||
-           rev->diffopt.flags.follow_renames)
+       if ((rev->diffopt.pickaxe_opts & DIFF_PICKAXE_KINDS_MASK) ||
+           rev->diffopt.filter || rev->diffopt.flags.follow_renames)
                rev->always_show_header = 0;
  
        if (source)
  
        if (decoration_style) {
                rev->show_decorations = 1;
 -              load_ref_decorations(decoration_style);
 +              load_ref_decorations(&decoration_filter, decoration_style);
        }
  
        if (rev->line_level_traverse)
diff --combined diff.c
index db4696fdf510d47dd6d235a1c04b8cc550c8e8fe,c2ee81a1fa4dfeaf40f558606639456815ff5d84..0a9a0cdf18f1ddd18f0939c49d29a311450d0be3
--- 1/diff.c
--- 2/diff.c
+++ b/diff.c
@@@ -246,7 -246,7 +246,7 @@@ static int parse_ws_error_highlight(con
   */
  void init_diff_ui_defaults(void)
  {
 -      diff_detect_rename_default = 1;
 +      diff_detect_rename_default = DIFF_DETECT_RENAME;
  }
  
  int git_diff_heuristic_config(const char *var, const char *value, void *cb)
@@@ -3210,8 -3210,6 +3210,8 @@@ static void builtin_diff(const char *na
                ecbdata.opt = o;
                ecbdata.header = header.len ? &header : NULL;
                xpp.flags = o->xdl_opts;
 +              xpp.anchors = o->anchors;
 +              xpp.anchors_nr = o->anchors_nr;
                xecfg.ctxlen = o->context;
                xecfg.interhunkctxlen = o->interhunkcontext;
                xecfg.flags = XDL_EMIT_FUNCNAMES;
@@@ -3304,8 -3302,6 +3304,8 @@@ static void builtin_diffstat(const cha
                memset(&xpp, 0, sizeof(xpp));
                memset(&xecfg, 0, sizeof(xecfg));
                xpp.flags = o->xdl_opts;
 +              xpp.anchors = o->anchors;
 +              xpp.anchors_nr = o->anchors_nr;
                xecfg.ctxlen = o->context;
                xecfg.interhunkctxlen = o->interhunkcontext;
                if (xdi_diff_outf(&mf1, &mf2, diffstat_consume, diffstat,
@@@ -4086,6 -4082,7 +4086,7 @@@ void diff_setup(struct diff_options *op
        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;
  
  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
         * inside contents.
         */
  
 -      if (DIFF_XDL_TST(options, IGNORE_WHITESPACE) ||
 -          DIFF_XDL_TST(options, IGNORE_WHITESPACE_CHANGE) ||
 -          DIFF_XDL_TST(options, IGNORE_WHITESPACE_AT_EOL))
 +      if ((options->xdl_opts & XDF_WHITESPACE_FLAGS))
                options->flags.diff_from_contents = 1;
        else
                options->flags.diff_from_contents = 0;
        /*
         * 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 -4486,23 +4488,23 @@@ static int parse_ws_error_highlight_opt
        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)
  {
                options->output_format |= DIFF_FORMAT_NUMSTAT;
        else if (!strcmp(arg, "--shortstat"))
                options->output_format |= DIFF_FORMAT_SHORTSTAT;
 -      else if (!strcmp(arg, "-X") || !strcmp(arg, "--dirstat"))
 -              return parse_dirstat_opt(options, "");
 -      else if (skip_prefix(arg, "-X", &arg))
 -              return parse_dirstat_opt(options, arg);
 -      else if (skip_prefix(arg, "--dirstat=", &arg))
 +      else if (skip_prefix(arg, "-X", &arg) ||
 +               skip_to_optional_arg(arg, "--dirstat", &arg))
                return parse_dirstat_opt(options, arg);
        else if (!strcmp(arg, "--cumulative"))
                return parse_dirstat_opt(options, "cumulative");
 -      else if (!strcmp(arg, "--dirstat-by-file"))
 -              return parse_dirstat_opt(options, "files");
 -      else if (skip_prefix(arg, "--dirstat-by-file=", &arg)) {
 +      else if (skip_to_optional_arg(arg, "--dirstat-by-file", &arg)) {
                parse_dirstat_opt(options, "files");
                return parse_dirstat_opt(options, arg);
        }
                return stat_opt(options, av);
  
        /* renames options */
 -      else if (starts_with(arg, "-B") || starts_with(arg, "--break-rewrites=") ||
 -               !strcmp(arg, "--break-rewrites")) {
 +      else if (starts_with(arg, "-B") ||
 +               skip_to_optional_arg(arg, "--break-rewrites", NULL)) {
                if ((options->break_opt = diff_scoreopt_parse(arg)) == -1)
                        return error("invalid argument to -B: %s", arg+2);
        }
 -      else if (starts_with(arg, "-M") || starts_with(arg, "--find-renames=") ||
 -               !strcmp(arg, "--find-renames")) {
 +      else if (starts_with(arg, "-M") ||
 +               skip_to_optional_arg(arg, "--find-renames", NULL)) {
                if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
                        return error("invalid argument to -M: %s", arg+2);
                options->detect_rename = DIFF_DETECT_RENAME;
        else if (!strcmp(arg, "-D") || !strcmp(arg, "--irreversible-delete")) {
                options->irreversible_delete = 1;
        }
 -      else if (starts_with(arg, "-C") || starts_with(arg, "--find-copies=") ||
 -               !strcmp(arg, "--find-copies")) {
 +      else if (starts_with(arg, "-C") ||
 +               skip_to_optional_arg(arg, "--find-copies", NULL)) {
                if (options->detect_rename == DIFF_DETECT_COPY)
                        options->flags.find_copies_harder = 1;
                if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
                options->flags.rename_empty = 1;
        else if (!strcmp(arg, "--no-rename-empty"))
                options->flags.rename_empty = 0;
 -      else if (!strcmp(arg, "--relative"))
 -              options->flags.relative_name = 1;
 -      else if (skip_prefix(arg, "--relative=", &arg)) {
 +      else if (skip_to_optional_arg_default(arg, "--relative", &arg, NULL)) {
                options->flags.relative_name = 1;
 -              options->prefix = arg;
 +              if (arg)
 +                      options->prefix = arg;
        }
  
        /* xdiff options */
                DIFF_XDL_SET(options, IGNORE_WHITESPACE_CHANGE);
        else if (!strcmp(arg, "--ignore-space-at-eol"))
                DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL);
 +      else if (!strcmp(arg, "--ignore-cr-at-eol"))
 +              DIFF_XDL_SET(options, IGNORE_CR_AT_EOL);
        else if (!strcmp(arg, "--ignore-blank-lines"))
                DIFF_XDL_SET(options, IGNORE_BLANK_LINES);
        else if (!strcmp(arg, "--indent-heuristic"))
                DIFF_XDL_SET(options, INDENT_HEURISTIC);
        else if (!strcmp(arg, "--no-indent-heuristic"))
                DIFF_XDL_CLR(options, INDENT_HEURISTIC);
 -      else if (!strcmp(arg, "--patience"))
 +      else if (!strcmp(arg, "--patience")) {
 +              int i;
                options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
 -      else if (!strcmp(arg, "--histogram"))
 +              /*
 +               * Both --patience and --anchored use PATIENCE_DIFF
 +               * internally, so remove any anchors previously
 +               * specified.
 +               */
 +              for (i = 0; i < options->anchors_nr; i++)
 +                      free(options->anchors[i]);
 +              options->anchors_nr = 0;
 +      } else if (!strcmp(arg, "--histogram"))
                options->xdl_opts = DIFF_WITH_ALG(options, HISTOGRAM_DIFF);
        else if ((argcount = parse_long_opt("diff-algorithm", av, &optarg))) {
                long value = parse_algorithm_value(optarg);
                options->xdl_opts &= ~XDF_DIFF_ALGORITHM_MASK;
                options->xdl_opts |= value;
                return argcount;
 +      } else if (skip_prefix(arg, "--anchored=", &arg)) {
 +              options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
 +              ALLOC_GROW(options->anchors, options->anchors_nr + 1,
 +                         options->anchors_alloc);
 +              options->anchors[options->anchors_nr++] = xstrdup(arg);
        }
  
        /* flags options */
        else if (!strcmp(arg, "--no-follow")) {
                options->flags.follow_renames = 0;
                options->flags.default_follow_renames = 0;
 -      } else if (!strcmp(arg, "--color"))
 -              options->use_color = 1;
 -      else if (skip_prefix(arg, "--color=", &arg)) {
 +      } else if (skip_to_optional_arg_default(arg, "--color", &arg, "always")) {
                int value = git_config_colorbool(NULL, arg);
                if (value < 0)
                        return error("option `color' expects \"always\", \"auto\", or \"never\"");
                if (cm < 0)
                        die("bad --color-moved argument: %s", arg);
                options->color_moved = cm;
 -      } else if (!strcmp(arg, "--color-words")) {
 +      } else if (skip_to_optional_arg_default(arg, "--color-words", &options->word_regex, NULL)) {
                options->use_color = 1;
                options->word_diff = DIFF_WORDS_COLOR;
        }
 -      else if (skip_prefix(arg, "--color-words=", &arg)) {
 -              options->use_color = 1;
 -              options->word_diff = DIFF_WORDS_COLOR;
 -              options->word_regex = arg;
 -      }
        else if (!strcmp(arg, "--word-diff")) {
                if (options->word_diff == DIFF_WORDS_NONE)
                        options->word_diff = DIFF_WORDS_PLAIN;
                options->flags.textconv_set_via_cmdline = 1;
        } else if (!strcmp(arg, "--no-textconv"))
                options->flags.allow_textconv = 0;
 -      else if (!strcmp(arg, "--ignore-submodules")) {
 -              options->flags.override_submodule_config = 1;
 -              handle_ignore_submodules_arg(options, "all");
 -      } else if (skip_prefix(arg, "--ignore-submodules=", &arg)) {
 +      else if (skip_to_optional_arg_default(arg, "--ignore-submodules", &arg, "all")) {
                options->flags.override_submodule_config = 1;
                handle_ignore_submodules_arg(options, arg);
 -      } else if (!strcmp(arg, "--submodule"))
 -              options->submodule_format = DIFF_SUBMODULE_LOG;
 -      else if (skip_prefix(arg, "--submodule=", &arg))
 +      } else if (skip_to_optional_arg_default(arg, "--submodule", &arg, "log"))
                return parse_submodule_opt(options, arg);
        else if (skip_prefix(arg, "--ws-error-highlight=", &arg))
                return parse_ws_error_highlight_opt(options, arg);
        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)
@@@ -4902,20 -4919,14 +4919,20 @@@ const char *diff_aligned_abbrev(const s
        int abblen;
        const char *abbrev;
  
 +      /* Do we want all 40 hex characters? */
        if (len == GIT_SHA1_HEXSZ)
                return oid_to_hex(oid);
  
 +      /* An abbreviated value is fine, possibly followed by an ellipsis. */
        abbrev = diff_abbrev_oid(oid, len);
 +
 +      if (!print_sha1_ellipsis())
 +              return abbrev;
 +
        abblen = strlen(abbrev);
  
        /*
 -       * In well-behaved cases, where the abbbreviated result is the
 +       * In well-behaved cases, where the abbreviated result is the
         * same as the requested length, append three dots after the
         * abbreviation (hence the whole logic is limited to the case
         * where abblen < 37); when the actual abbreviated result is a
@@@ -5460,7 -5471,7 +5477,7 @@@ void diff_warn_rename_limit(const char 
                warning(_(rename_limit_warning));
        else
                return;
 -      if (0 < needed && needed < 32767)
 +      if (0 < needed)
                warning(_(rename_limit_advice), varname, needed);
  }
  
@@@ -5783,7 -5794,7 +5800,7 @@@ void diffcore_std(struct diff_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);
diff --combined diff.h
index 7cf276f07733afdf14618a8c47fce33c89a41e24,8a56cac2ad1c89842187f913741d557138352a05..6bd278aac11a4349ce76602113e45e31ae1229de
--- 1/diff.h
--- 2/diff.h
+++ b/diff.h
@@@ -7,6 -7,7 +7,7 @@@
  #include "tree-walk.h"
  #include "pathspec.h"
  #include "object.h"
+ #include "oidset.h"
  
  struct rev_info;
  struct diff_options;
@@@ -91,7 -92,6 +92,6 @@@ struct diff_flags 
        unsigned override_submodule_config:1;
        unsigned dirstat_by_line:1;
        unsigned funccontext:1;
-       unsigned pickaxe_ignore_case:1;
        unsigned default_follow_renames:1;
  };
  
@@@ -146,7 -146,7 +146,7 @@@ struct diff_options 
        int skip_stat_unmatch;
        int line_termination;
        int output_format;
-       int pickaxe_opts;
+       unsigned pickaxe_opts;
        int rename_score;
        int rename_limit;
        int needed_rename_limit;
        const char *stat_sep;
        long xdl_opts;
  
 +      /* see Documentation/diff-options.txt */
 +      char **anchors;
 +      size_t anchors_nr, anchors_alloc;
 +
        int stat_width;
        int stat_name_width;
        int stat_graph_width;
        enum diff_words_type word_diff;
        enum diff_submodule_format submodule_format;
  
+       struct oidset *objfind;
        /* this is set by diffcore for DIFF_FORMAT_PATCH */
        int found_changes;
  
@@@ -330,6 -328,13 +332,13 @@@ extern void diff_setup_done(struct diff
  
  #define DIFF_PICKAXE_KIND_S   4 /* traditional plumbing counter */
  #define DIFF_PICKAXE_KIND_G   8 /* grep in the patch */
+ #define DIFF_PICKAXE_KIND_OBJFIND     16 /* specific object IDs */
+ #define DIFF_PICKAXE_KINDS_MASK (DIFF_PICKAXE_KIND_S | \
+                                DIFF_PICKAXE_KIND_G | \
+                                DIFF_PICKAXE_KIND_OBJFIND)
+ #define DIFF_PICKAXE_IGNORE_CASE      32
  
  extern void diffcore_std(struct diff_options *);
  extern void diffcore_fix_diff_index(struct diff_options *);
diff --combined revision.c
index 1f7454c947a683eb2df28e51504bf67ebe8379cd,30f65b3bbdb2df3f84fac48c1550c8cf247184f5..a60628fbff96c413f9df5641d0bece45d89b721f
@@@ -1832,7 -1832,7 +1832,7 @@@ static int handle_revision_opt(struct r
                revs->simplify_by_decoration = 1;
                revs->limited = 1;
                revs->prune = 1;
 -              load_ref_decorations(DECORATE_SHORT_REFS);
 +              load_ref_decorations(NULL, DECORATE_SHORT_REFS);
        } else if (!strcmp(arg, "--date-order")) {
                revs->sort_order = REV_SORT_BY_COMMIT_DATE;
                revs->topo_order = 1;
                revs->dense = 0;
        } else if (!strcmp(arg, "--show-all")) {
                revs->show_all = 1;
 +      } else if (!strcmp(arg, "--in-commit-order")) {
 +              revs->tree_blobs_in_commit_order = 1;
        } else if (!strcmp(arg, "--remove-empty")) {
                revs->remove_empty_trees = 1;
        } else if (!strcmp(arg, "--merges")) {
                revs->grep_filter.pattern_type_option = GREP_PATTERN_TYPE_ERE;
        } else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) {
                revs->grep_filter.ignore_case = 1;
-               revs->diffopt.flags.pickaxe_ignore_case = 1;
+               revs->diffopt.pickaxe_opts |= DIFF_PICKAXE_IGNORE_CASE;
        } else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) {
                revs->grep_filter.pattern_type_option = GREP_PATTERN_TYPE_FIXED;
        } else if (!strcmp(arg, "--perl-regexp") || !strcmp(arg, "-P")) {
@@@ -2409,11 -2407,14 +2409,14 @@@ int setup_revisions(int argc, const cha
                revs->diff = 1;
  
        /* Pickaxe, diff-filter and rename following need diffs */
-       if (revs->diffopt.pickaxe ||
+       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->topo_order)
                revs->limited = 1;
  
@@@ -2862,7 -2863,8 +2865,7 @@@ int prepare_revision_walk(struct rev_in
                        }
                }
        }
 -      if (!revs->leak_pending)
 -              object_array_clear(&old_pending);
 +      object_array_clear(&old_pending);
  
        /* Signal whether we need per-parent treesame decoration */
        if (revs->simplify_merges ||