config: Introduce diff.algorithm variable
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 16 Jan 2013 07:51:57 +0000 (08:51 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 16 Jan 2013 17:37:45 +0000 (09:37 -0800)
Some users or projects prefer different algorithms over others, e.g.
patience over myers or similar. However, specifying appropriate
argument every time diff is to be used is impractical. Moreover,
creating an alias doesn't play nicely with other tools based on diff
(git-show for instance). Hence, a configuration variable which is able
to set specific algorithm is needed. For now, these four values are
accepted: 'myers' (which has the same effect as not setting the config
variable at all), 'minimal', 'patience' and 'histogram'.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/diff-config.txt
contrib/completion/git-completion.bash
diff.c
index 4314ad0fbb617b9f4c9c4e3d45f5d08f89259e2b..b8a8724f6f87fdc820f0d686078e0466adbad204 100644 (file)
@@ -155,3 +155,20 @@ diff.tool::
        "kompare".  Any other value is treated as a custom diff tool,
        and there must be a corresponding `difftool.<tool>.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".
+--
++
index 383518ca6025878770bc8349dc36a960f8fb5af3..33e25dc08cfe11df2b5eb04beec33bac167be462 100644 (file)
@@ -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 732d4c227595873bb94224da618ce5612a7415af..d2be7777930eee055ad317cbb24a0d65f4ce441b 100644 (file)
--- 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 = "";