Skip to content

Commit 5b16287

Browse files
mhaggergitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ce564eb commit 5b16287

File tree

8 files changed

+70
-19
lines changed

8 files changed

+70
-19
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
--indent-heuristic::
2+
--no-indent-heuristic::
3+
--compaction-heuristic::
4+
--no-compaction-heuristic::
5+
These are to help debugging and tuning experimental heuristics
6+
(which are off by default) that shift diff hunk boundaries to
7+
make patches easier to read.

Documentation/diff-options.txt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,7 @@ ifndef::git-format-patch[]
6363
Synonym for `-p --raw`.
6464
endif::git-format-patch[]
6565

66-
--indent-heuristic::
67-
--no-indent-heuristic::
68-
--compaction-heuristic::
69-
--no-compaction-heuristic::
70-
These are to help debugging and tuning experimental heuristics
71-
(which are off by default) that shift diff hunk boundaries to
72-
make patches easier to read.
66+
include::diff-heuristic-options.txt[]
7367

7468
--minimal::
7569
Spend extra time to make sure the smallest possible

Documentation/git-annotate.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ familiar command name for people coming from other SCM systems.
2323
OPTIONS
2424
-------
2525
include::blame-options.txt[]
26+
include::diff-heuristic-options.txt[]
2627

2728
SEE ALSO
2829
--------

Documentation/git-blame.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ include::blame-options.txt[]
8989
abbreviated object name, use <n>+1 digits. Note that 1 column
9090
is used for a caret to mark the boundary commit.
9191

92+
include::diff-heuristic-options.txt[]
93+
9294

9395
THE PORCELAIN FORMAT
9496
--------------------

builtin/blame.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2221,6 +2221,8 @@ static int git_blame_config(const char *var, const char *value, void *cb)
22212221
return 0;
22222222
}
22232223

2224+
if (git_diff_heuristic_config(var, value, cb) < 0)
2225+
return -1;
22242226
if (userdiff_config(var, value) < 0)
22252227
return -1;
22262228

@@ -2542,6 +2544,15 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
25422544
OPT_BIT('s', NULL, &output_option, N_("Suppress author name and timestamp (Default: off)"), OUTPUT_NO_AUTHOR),
25432545
OPT_BIT('e', "show-email", &output_option, N_("Show author email instead of name (Default: off)"), OUTPUT_SHOW_EMAIL),
25442546
OPT_BIT('w', NULL, &xdl_opts, N_("Ignore whitespace differences"), XDF_IGNORE_WHITESPACE),
2547+
2548+
/*
2549+
* The following two options are parsed by parse_revision_opt()
2550+
* and are only included here to get included in the "-h"
2551+
* output:
2552+
*/
2553+
{ 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 },
2554+
{ 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 },
2555+
25452556
OPT_BIT(0, "minimal", &xdl_opts, N_("Spend extra cycles to find better match"), XDF_NEED_MINIMAL),
25462557
OPT_STRING('S', NULL, &revs_file, N_("file"), N_("Use revisions from <file> instead of calling git-rev-list")),
25472558
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)
25882599
}
25892600
parse_done:
25902601
no_whole_file_rename = !DIFF_OPT_TST(&revs.diffopt, FOLLOW_RENAMES);
2602+
xdl_opts |= revs.diffopt.xdl_opts & (XDF_COMPACTION_HEURISTIC | XDF_INDENT_HEURISTIC);
25912603
DIFF_OPT_CLR(&revs.diffopt, FOLLOW_RENAMES);
25922604
argc = parse_options_end(&ctx);
25932605

diff.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,21 @@ void init_diff_ui_defaults(void)
175175
diff_detect_rename_default = 1;
176176
}
177177

178+
int git_diff_heuristic_config(const char *var, const char *value, void *cb)
179+
{
180+
if (!strcmp(var, "diff.indentheuristic")) {
181+
diff_indent_heuristic = git_config_bool(var, value);
182+
if (diff_indent_heuristic)
183+
diff_compaction_heuristic = 0;
184+
}
185+
if (!strcmp(var, "diff.compactionheuristic")) {
186+
diff_compaction_heuristic = git_config_bool(var, value);
187+
if (diff_compaction_heuristic)
188+
diff_indent_heuristic = 0;
189+
}
190+
return 0;
191+
}
192+
178193
int git_diff_ui_config(const char *var, const char *value, void *cb)
179194
{
180195
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)
191206
diff_detect_rename_default = git_config_rename(var, value);
192207
return 0;
193208
}
194-
if (!strcmp(var, "diff.indentheuristic")) {
195-
diff_indent_heuristic = git_config_bool(var, value);
196-
if (diff_indent_heuristic)
197-
diff_compaction_heuristic = 0;
198-
return 0;
199-
}
200-
if (!strcmp(var, "diff.compactionheuristic")) {
201-
diff_compaction_heuristic = git_config_bool(var, value);
202-
if (diff_compaction_heuristic)
203-
diff_indent_heuristic = 0;
204-
return 0;
205-
}
206209
if (!strcmp(var, "diff.autorefreshindex")) {
207210
diff_auto_refresh_index = git_config_bool(var, value);
208211
return 0;
@@ -243,6 +246,8 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)
243246
return 0;
244247
}
245248

249+
if (git_diff_heuristic_config(var, value, cb) < 0)
250+
return -1;
246251
if (git_color_config(var, value, cb) < 0)
247252
return -1;
248253

diff.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ extern int parse_long_opt(const char *opt, const char **argv,
266266
const char **optarg);
267267

268268
extern int git_diff_basic_config(const char *var, const char *value, void *cb);
269+
extern int git_diff_heuristic_config(const char *var, const char *value, void *cb);
269270
extern void init_diff_ui_defaults(void);
270271
extern int git_diff_ui_config(const char *var, const char *value, void *cb);
271272
extern void diff_setup(struct diff_options *);

t/t4061-diff-indent.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ compare_diff () {
1414
test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
1515
}
1616

17+
# Compare blame output using the expectation for a diff as reference.
18+
# Only look for the lines coming from non-boundary commits.
19+
compare_blame () {
20+
sed -n -e "1,4d" -e "s/^\+//p" <"$1" >.tmp-1
21+
sed -ne "s/^[^^][^)]*) *//p" <"$2" >.tmp-2
22+
test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
23+
}
24+
1725
test_expect_success 'prepare' '
1826
cat <<-\EOF >spaces.txt &&
1927
1
@@ -184,4 +192,25 @@ test_expect_success 'diff: nice functions with --indent-heuristic' '
184192
compare_diff functions-compacted-expect out-compacted
185193
'
186194

195+
test_expect_success 'blame: ugly spaces' '
196+
git blame old..new -- spaces.txt >out-blame &&
197+
compare_blame spaces-expect out-blame
198+
'
199+
200+
test_expect_success 'blame: nice spaces with --indent-heuristic' '
201+
git blame --indent-heuristic old..new -- spaces.txt >out-blame-compacted &&
202+
compare_blame spaces-compacted-expect out-blame-compacted
203+
'
204+
205+
test_expect_success 'blame: nice spaces with diff.indentHeuristic' '
206+
git -c diff.indentHeuristic=true blame old..new -- spaces.txt >out-blame-compacted2 &&
207+
compare_blame spaces-compacted-expect out-blame-compacted2
208+
'
209+
210+
test_expect_success 'blame: --no-indent-heuristic overrides config' '
211+
git -c diff.indentHeuristic=true blame --no-indent-heuristic old..new -- spaces.txt >out-blame2 &&
212+
git blame old..new -- spaces.txt >out-blame &&
213+
compare_blame spaces-expect out-blame2
214+
'
215+
187216
test_done

0 commit comments

Comments
 (0)