diff options
author | Michael Haggerty <mhagger@alum.mit.edu> | 2016-09-05 11:44:53 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-09-19 10:25:11 -0700 |
commit | 5b162879e93dab3b4bcd66afdbea3a96660abd7d (patch) | |
tree | 409c0b32b3ff0ae9be653d723900fc61c8eb909c | |
parent | ce564eb1bd541a87152e3546fb7d7a2b460df7ed (diff) | |
download | git-5b162879e93dab3b4bcd66afdbea3a96660abd7d.tar.gz |
blame: honor the diff heuristic options and config
Teach "git blame" and "git annotate" the --compaction-heuristic and
--indent-heuristic options that are now supported by "git diff".
Also teach them to honor the `diff.compactionHeuristic` and
`diff.indentHeuristic` configuration options.
It would be conceivable to introduce separate configuration options for
"blame" and "annotate"; for example `blame.compactionHeuristic` and
`blame.indentHeuristic`. But it would be confusing to users if blame
output is inconsistent with diff output, so it makes more sense for them
to respect the same configuration.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | Documentation/diff-heuristic-options.txt | 7 | ||||
-rw-r--r-- | Documentation/diff-options.txt | 8 | ||||
-rw-r--r-- | Documentation/git-annotate.txt | 1 | ||||
-rw-r--r-- | Documentation/git-blame.txt | 2 | ||||
-rw-r--r-- | builtin/blame.c | 12 | ||||
-rw-r--r-- | diff.c | 29 | ||||
-rw-r--r-- | diff.h | 1 | ||||
-rwxr-xr-x | t/t4061-diff-indent.sh | 29 |
8 files changed, 70 insertions, 19 deletions
diff --git a/Documentation/diff-heuristic-options.txt b/Documentation/diff-heuristic-options.txt new file mode 100644 index 0000000000..36cb549df9 --- /dev/null +++ b/Documentation/diff-heuristic-options.txt @@ -0,0 +1,7 @@ +--indent-heuristic:: +--no-indent-heuristic:: +--compaction-heuristic:: +--no-compaction-heuristic:: + These are to help debugging and tuning experimental heuristics + (which are off by default) that shift diff hunk boundaries to + make patches easier to read. diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 3a07f6f475..0364061a4a 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -63,13 +63,7 @@ ifndef::git-format-patch[] Synonym for `-p --raw`. endif::git-format-patch[] ---indent-heuristic:: ---no-indent-heuristic:: ---compaction-heuristic:: ---no-compaction-heuristic:: - These are to help debugging and tuning experimental heuristics - (which are off by default) that shift diff hunk boundaries to - make patches easier to read. +include::diff-heuristic-options.txt[] --minimal:: Spend extra time to make sure the smallest possible diff --git a/Documentation/git-annotate.txt b/Documentation/git-annotate.txt index 05fd482b74..94be4b85e0 100644 --- a/Documentation/git-annotate.txt +++ b/Documentation/git-annotate.txt @@ -23,6 +23,7 @@ familiar command name for people coming from other SCM systems. OPTIONS ------- include::blame-options.txt[] +include::diff-heuristic-options.txt[] SEE ALSO -------- diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt index ba5417567c..9dccb3319b 100644 --- a/Documentation/git-blame.txt +++ b/Documentation/git-blame.txt @@ -89,6 +89,8 @@ include::blame-options.txt[] abbreviated object name, use <n>+1 digits. Note that 1 column is used for a caret to mark the boundary commit. +include::diff-heuristic-options.txt[] + THE PORCELAIN FORMAT -------------------- diff --git a/builtin/blame.c b/builtin/blame.c index 1e214bd4ec..f82b0a0d94 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -2221,6 +2221,8 @@ static int git_blame_config(const char *var, const char *value, void *cb) return 0; } + if (git_diff_heuristic_config(var, value, cb) < 0) + return -1; if (userdiff_config(var, value) < 0) return -1; @@ -2542,6 +2544,15 @@ int cmd_blame(int argc, const char **argv, const char *prefix) 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")), @@ -2588,6 +2599,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) } 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); @@ -175,6 +175,21 @@ void init_diff_ui_defaults(void) diff_detect_rename_default = 1; } +int git_diff_heuristic_config(const char *var, const char *value, void *cb) +{ + if (!strcmp(var, "diff.indentheuristic")) { + diff_indent_heuristic = git_config_bool(var, value); + if (diff_indent_heuristic) + diff_compaction_heuristic = 0; + } + if (!strcmp(var, "diff.compactionheuristic")) { + diff_compaction_heuristic = git_config_bool(var, value); + if (diff_compaction_heuristic) + diff_indent_heuristic = 0; + } + return 0; +} + int git_diff_ui_config(const char *var, const char *value, void *cb) { if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) { @@ -191,18 +206,6 @@ int git_diff_ui_config(const char *var, const char *value, void *cb) diff_detect_rename_default = git_config_rename(var, value); return 0; } - if (!strcmp(var, "diff.indentheuristic")) { - diff_indent_heuristic = git_config_bool(var, value); - if (diff_indent_heuristic) - diff_compaction_heuristic = 0; - return 0; - } - if (!strcmp(var, "diff.compactionheuristic")) { - diff_compaction_heuristic = git_config_bool(var, value); - if (diff_compaction_heuristic) - diff_indent_heuristic = 0; - return 0; - } if (!strcmp(var, "diff.autorefreshindex")) { diff_auto_refresh_index = git_config_bool(var, value); return 0; @@ -243,6 +246,8 @@ int git_diff_ui_config(const char *var, const char *value, void *cb) return 0; } + if (git_diff_heuristic_config(var, value, cb) < 0) + return -1; if (git_color_config(var, value, cb) < 0) return -1; @@ -266,6 +266,7 @@ extern int parse_long_opt(const char *opt, const char **argv, const char **optarg); extern int git_diff_basic_config(const char *var, const char *value, void *cb); +extern int git_diff_heuristic_config(const char *var, const char *value, void *cb); extern void init_diff_ui_defaults(void); extern int git_diff_ui_config(const char *var, const char *value, void *cb); extern void diff_setup(struct diff_options *); diff --git a/t/t4061-diff-indent.sh b/t/t4061-diff-indent.sh index 0a65b585af..556450609b 100755 --- a/t/t4061-diff-indent.sh +++ b/t/t4061-diff-indent.sh @@ -14,6 +14,14 @@ compare_diff () { test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2 } +# Compare blame output using the expectation for a diff as reference. +# Only look for the lines coming from non-boundary commits. +compare_blame () { + sed -n -e "1,4d" -e "s/^\+//p" <"$1" >.tmp-1 + sed -ne "s/^[^^][^)]*) *//p" <"$2" >.tmp-2 + test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2 +} + test_expect_success 'prepare' ' cat <<-\EOF >spaces.txt && 1 @@ -184,4 +192,25 @@ test_expect_success 'diff: nice functions with --indent-heuristic' ' compare_diff functions-compacted-expect out-compacted ' +test_expect_success 'blame: ugly spaces' ' + git blame old..new -- spaces.txt >out-blame && + compare_blame spaces-expect out-blame +' + +test_expect_success 'blame: nice spaces with --indent-heuristic' ' + git blame --indent-heuristic old..new -- spaces.txt >out-blame-compacted && + compare_blame spaces-compacted-expect out-blame-compacted +' + +test_expect_success 'blame: nice spaces with diff.indentHeuristic' ' + git -c diff.indentHeuristic=true blame old..new -- spaces.txt >out-blame-compacted2 && + compare_blame spaces-compacted-expect out-blame-compacted2 +' + +test_expect_success 'blame: --no-indent-heuristic overrides config' ' + git -c diff.indentHeuristic=true blame --no-indent-heuristic old..new -- spaces.txt >out-blame2 && + git blame old..new -- spaces.txt >out-blame && + compare_blame spaces-expect out-blame2 +' + test_done |