diff --git a/Documentation/diff-config.txt b/Documentation/diff-config.txt index 4314ad0fbb..b8a8724f6f 100644 --- a/Documentation/diff-config.txt +++ b/Documentation/diff-config.txt @@ -155,3 +155,20 @@ diff.tool:: "kompare". Any other value is treated as a custom diff tool, and there must be a corresponding `difftool..cmd` option. + +diff.algorithm:: + Choose a diff algorithm. The variants are as follows: ++ +-- +`default`, `myers`;; + The basic greedy diff algorithm. Currently, this is the default. +`minimal`;; + Spend extra time to make sure the smallest possible diff is + produced. +`patience`;; + Use "patience diff" algorithm when generating patches. +`histogram`;; + This algorithm extends the patience algorithm to "support + low-occurrence common elements". +-- ++ diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 383518ca60..33e25dc08c 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1839,6 +1839,7 @@ _git_config () diff.suppressBlankEmpty diff.tool diff.wordRegex + diff.algorithm difftool. difftool.prompt fetch.recurseSubmodules diff --git a/diff.c b/diff.c index 732d4c2275..d2be777793 100644 --- a/diff.c +++ b/diff.c @@ -36,6 +36,7 @@ static int diff_no_prefix; static int diff_stat_graph_width; static int diff_dirstat_permille_default = 30; static struct diff_options default_diff_options; +static long diff_algorithm; static char diff_colors[][COLOR_MAXLEN] = { GIT_COLOR_RESET, @@ -143,6 +144,21 @@ static int git_config_rename(const char *var, const char *value) return git_config_bool(var,value) ? DIFF_DETECT_RENAME : 0; } +static long parse_algorithm_value(const char *value) +{ + if (!value) + return -1; + else if (!strcasecmp(value, "myers") || !strcasecmp(value, "default")) + return 0; + else if (!strcasecmp(value, "minimal")) + return XDF_NEED_MINIMAL; + else if (!strcasecmp(value, "patience")) + return XDF_PATIENCE_DIFF; + else if (!strcasecmp(value, "histogram")) + return XDF_HISTOGRAM_DIFF; + return -1; +} + /* * These are to give UI layer defaults. * The core-level commands such as git-diff-files should @@ -196,6 +212,13 @@ int git_diff_ui_config(const char *var, const char *value, void *cb) return 0; } + if (!strcmp(var, "diff.algorithm")) { + diff_algorithm = parse_algorithm_value(value); + if (diff_algorithm < 0) + return -1; + return 0; + } + if (git_color_config(var, value, cb) < 0) return -1; @@ -3213,6 +3236,7 @@ void diff_setup(struct diff_options *options) options->add_remove = diff_addremove; options->use_color = diff_use_color_default; options->detect_rename = diff_detect_rename_default; + options->xdl_opts |= diff_algorithm; if (diff_no_prefix) { options->a_prefix = options->b_prefix = "";