unsigned largest_score = 0;
struct blame_entry *e;
int compute_auto_abbrev = (abbrev < 0);
- int auto_abbrev = default_abbrev;
+ int auto_abbrev = DEFAULT_ABBREV;
for (e = sb->ent; e; e = e->next) {
struct origin *suspect = e->suspect;
return 0;
}
+ if (git_diff_heuristic_config(var, value, cb) < 0)
+ return -1;
if (userdiff_config(var, value) < 0)
return -1;
return xstrdup_or_null(name);
}
+static const char *dwim_reverse_initial(struct scoreboard *sb)
+{
+ /*
+ * DWIM "git blame --reverse ONE -- PATH" as
+ * "git blame --reverse ONE..HEAD -- PATH" but only do so
+ * when it makes sense.
+ */
+ struct object *obj;
+ struct commit *head_commit;
+ unsigned char head_sha1[20];
+
+ if (sb->revs->pending.nr != 1)
+ return NULL;
+
+ /* Is that sole rev a committish? */
+ obj = sb->revs->pending.objects[0].item;
+ obj = deref_tag(obj, NULL, 0);
+ if (obj->type != OBJ_COMMIT)
+ return NULL;
+
+ /* Do we have HEAD? */
+ if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_sha1, NULL))
+ return NULL;
+ head_commit = lookup_commit_reference_gently(head_sha1, 1);
+ if (!head_commit)
+ return NULL;
+
+ /* Turn "ONE" into "ONE..HEAD" then */
+ obj->flags |= UNINTERESTING;
+ add_pending_object(sb->revs, &head_commit->object, "HEAD");
+
+ sb->final = (struct commit *)obj;
+ return sb->revs->pending.objects[0].name;
+}
+
static char *prepare_initial(struct scoreboard *sb)
{
int i;
if (obj->type != OBJ_COMMIT)
die("Non commit %s?", revs->pending.objects[i].name);
if (sb->final)
- die("More than one commit to dig down to %s and %s?",
+ die("More than one commit to dig up from, %s and %s?",
revs->pending.objects[i].name,
final_commit_name);
sb->final = (struct commit *) obj;
final_commit_name = revs->pending.objects[i].name;
}
+
+ if (!final_commit_name)
+ final_commit_name = dwim_reverse_initial(sb);
if (!final_commit_name)
- die("No commit to dig down to?");
+ die("No commit to dig up from?");
return xstrdup(final_commit_name);
}
OPT_BIT('s', NULL, &output_option, N_("Suppress author name and timestamp (Default: off)"), OUTPUT_NO_AUTHOR),
OPT_BIT('e', "show-email", &output_option, N_("Show author email instead of name (Default: off)"), OUTPUT_SHOW_EMAIL),
OPT_BIT('w', NULL, &xdl_opts, N_("Ignore whitespace differences"), XDF_IGNORE_WHITESPACE),
+
+ /*
+ * The following two options are parsed by parse_revision_opt()
+ * and are only included here to get included in the "-h"
+ * output:
+ */
+ { OPTION_LOWLEVEL_CALLBACK, 0, "indent-heuristic", NULL, NULL, N_("Use an experimental indent-based heuristic to improve diffs"), PARSE_OPT_NOARG, parse_opt_unknown_cb },
+ { OPTION_LOWLEVEL_CALLBACK, 0, "compaction-heuristic", NULL, NULL, N_("Use an experimental blank-line-based heuristic to improve diffs"), PARSE_OPT_NOARG, parse_opt_unknown_cb },
+
OPT_BIT(0, "minimal", &xdl_opts, N_("Spend extra cycles to find better match"), XDF_NEED_MINIMAL),
OPT_STRING('S', NULL, &revs_file, N_("file"), N_("Use revisions from <file> instead of calling git-rev-list")),
OPT_STRING(0, "contents", &contents_from, N_("file"), N_("Use <file>'s contents as the final image")),
}
parse_done:
no_whole_file_rename = !DIFF_OPT_TST(&revs.diffopt, FOLLOW_RENAMES);
+ xdl_opts |= revs.diffopt.xdl_opts & (XDF_COMPACTION_HEURISTIC | XDF_INDENT_HEURISTIC);
DIFF_OPT_CLR(&revs.diffopt, FOLLOW_RENAMES);
argc = parse_options_end(&ctx);