xdiff: implement empty line chunk heuristic
In order to produce the smallest possible diff and combine several diff hunks together, we implement a heuristic from GNU Diff which moves diff hunks forward as far as possible when we find common context above and below a diff hunk. This sometimes produces less readable diffs when writing C, Shell, or other programming languages, ie: ... /* + * + * + */ + +/* ... instead of the more readable equivalent of ... +/* + * + * + */ + /* ... Implement the following heuristic to (optionally) produce the desired output. If there are diff chunks which can be shifted around, shift each hunk such that the last common empty line is below the chunk with the rest of the context above. This heuristic appears to resolve the above example and several other common issues without producing significantly weird results. However, as with any heuristic it is not really known whether this will always be more optimal. Thus, it can be disabled via diff.compactionHeuristic. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
92e5b62fec
commit
d634d61ed6
11
diff.c
11
diff.c
@ -25,6 +25,7 @@
|
||||
#endif
|
||||
|
||||
static int diff_detect_rename_default;
|
||||
static int diff_compaction_heuristic = 1;
|
||||
static int diff_rename_limit_default = 400;
|
||||
static int diff_suppress_blank_empty;
|
||||
static int diff_use_color_default = -1;
|
||||
@ -183,6 +184,10 @@ 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.compactionheuristic")) {
|
||||
diff_compaction_heuristic = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(var, "diff.autorefreshindex")) {
|
||||
diff_auto_refresh_index = git_config_bool(var, value);
|
||||
return 0;
|
||||
@ -3235,6 +3240,8 @@ void diff_setup(struct diff_options *options)
|
||||
options->use_color = diff_use_color_default;
|
||||
options->detect_rename = diff_detect_rename_default;
|
||||
options->xdl_opts |= diff_algorithm;
|
||||
if (diff_compaction_heuristic)
|
||||
DIFF_XDL_SET(options, COMPACTION_HEURISTIC);
|
||||
|
||||
options->orderfile = diff_order_file_cfg;
|
||||
|
||||
@ -3712,6 +3719,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
|
||||
DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL);
|
||||
else if (!strcmp(arg, "--ignore-blank-lines"))
|
||||
DIFF_XDL_SET(options, IGNORE_BLANK_LINES);
|
||||
else if (!strcmp(arg, "--compaction-heuristic"))
|
||||
DIFF_XDL_SET(options, COMPACTION_HEURISTIC);
|
||||
else if (!strcmp(arg, "--no-compaction-heuristic"))
|
||||
DIFF_XDL_CLR(options, COMPACTION_HEURISTIC);
|
||||
else if (!strcmp(arg, "--patience"))
|
||||
options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
|
||||
else if (!strcmp(arg, "--histogram"))
|
||||
|
Reference in New Issue
Block a user