[PATCH] diff: Introduce diff.algorithm variable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Some users have preference over various diff algorithms. However,
now they are forced to use appropriate argument every time they
run git-diff and tools using it. This is impractical. Therefore
create new variable which can set preferred algorithm. Of course,
this can be overridden on command line via --diff-algorithm=*.
Accepted values are myers (default), histogram, minimal, patience.

Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx>
---
This is basically v2 for:

   http://www.spinics.net/lists/git/msg176100.html

As we agreed on list, I've switched from diff.patience to
diff.algorithm and created new argument --diff-algorithm.

Please keep me CC'ed as I am not signed into the list.

 Documentation/diff-config.txt          |   21 +++++++++++++++++++
 Documentation/diff-options.txt         |   23 +++++++++++++++++++++
 contrib/completion/git-completion.bash |   13 +++++++++++
 diff.c                                 |   35 ++++++++++++++++++++++++++++++++
 4 files changed, 92 insertions(+), 0 deletions(-)

diff --git a/Documentation/diff-config.txt b/Documentation/diff-config.txt
index 6aa1be0..1047e81 100644
--- a/Documentation/diff-config.txt
+++ b/Documentation/diff-config.txt
@@ -1,3 +1,24 @@
+diff.algorithm::
+    Choose a diff algorithm.  The variants are as follows:
++
+--
+histogram::
+    This is the fastest algorithm.
+
+myers::
+    The classical Myers diff algorithm. This is the default.
+
+minimal::
+    Like 'myers', but spend extra time making sure that the diff
+    is the shortest possible for the set of changes performed.
+
+patience::
+    The patience diff algorithm, which first matches unique lines
+    with each other.  This sometimes results in more readable (if
+    longer) patches than the other algorithms.
+--
++
+
 diff.autorefreshindex::
 	When using 'git diff' to compare with work tree
 	files, do not consider stat-only change as changed.
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 7d4566f..4e8bc5b 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -55,6 +55,29 @@ endif::git-format-patch[]
 --histogram::
 	Generate a diff using the "histogram diff" algorithm.
 
+--diff-algorithm={histogram|myers|minimal|patience}::
+    Choose a diff algorithm. The defaults are controlled
+    by the `diff.algorithm` configuration variable
+    (see linkgit:git-config[1]). The variants are as follows:
++
+--
+histogram::
+    This is the fastest algorithm.
+
+myers::
+    The classical Myers diff algorithm. This is the default.
+
+minimal::
+    Like 'myers', but spend extra time making sure that the diff
+    is the shortest possible for the set of changes performed.
+
+patience::
+    The patience diff algorithm, which first matches unique lines
+    with each other.  This sometimes results in more readable (if
+    longer) patches than the other algorithms.
+--
++
+
 --stat[=<width>[,<name-width>[,<count>]]]::
 	Generate a diffstat. By default, as much space as necessary
 	will be used for the filename part, and the rest for the graph
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index fba076d..d54f3a3 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1299,6 +1299,7 @@ __git_diff_common_options="--stat --numstat --shortstat --summary
 			--raw
 			--dirstat --dirstat= --dirstat-by-file
 			--dirstat-by-file= --cumulative
+			--diff-algorithm=
 "
 
 _git_diff ()
@@ -1306,6 +1307,10 @@ _git_diff ()
 	__git_has_doubledash && return
 
 	case "$cur" in
+	--diff-algorithm=*)
+		__gitcomp "myers histogram minimal patience"
+		return
+		;;
 	--*)
 		__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
 			--base --ours --theirs --no-index
@@ -1569,6 +1574,10 @@ _git_log ()
 		__gitcomp "long short" "" "${cur##--decorate=}"
 		return
 		;;
+    --diff-algorithm=*)
+		__gitcomp "myers histogram minimal patience"
+		return
+		;;
 	--*)
 		__gitcomp "
 			$__git_log_common_options
@@ -2376,6 +2385,10 @@ _git_show ()
 			" "" "${cur#*=}"
 		return
 		;;
+	--diff-algorithm=*)
+		__gitcomp "myers histogram minimal patience"
+		return
+		;;
 	--*)
 		__gitcomp "--pretty= --format= --abbrev-commit --oneline
 			$__git_diff_common_options
diff --git a/diff.c b/diff.c
index 377ec1e..f5c965b 100644
--- a/diff.c
+++ b/diff.c
@@ -34,6 +34,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 int diff_algorithm = 0;
 
 static char diff_colors[][COLOR_MAXLEN] = {
 	GIT_COLOR_RESET,
@@ -47,6 +48,20 @@ static char diff_colors[][COLOR_MAXLEN] = {
 	GIT_COLOR_NORMAL,	/* FUNCINFO */
 };
 
+static int diff_algorithm_parse(const char *alg)
+{
+	if (!alg || !strcmp(alg, "myers"))
+		return 0;
+	else if (!strcmp(alg, "patience"))
+		return XDF_PATIENCE_DIFF;
+	else if (!strcmp(alg, "histogram"))
+		return XDF_HISTOGRAM_DIFF;
+	else if (!strcmp(alg, "minimal"))
+		return XDF_NEED_MINIMAL;
+
+	return -1;
+}
+
 static int parse_diff_color_slot(const char *var, int ofs)
 {
 	if (!strcasecmp(var+ofs, "plain"))
@@ -169,6 +184,12 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)
 	if (!strcmp(var, "diff.ignoresubmodules"))
 		handle_ignore_submodules_arg(&default_diff_options, value);
 
+	if (!strcmp(var, "diff.algorithm")) {
+		if ((diff_algorithm = diff_algorithm_parse(value)) < 0)
+			die("bad diff.algorithm value: %s", value);
+		return 0;
+	}
+
 	if (git_color_config(var, value, cb) < 0)
 		return -1;
 
@@ -3250,6 +3271,9 @@ int diff_setup_done(struct diff_options *options)
 		DIFF_OPT_SET(options, EXIT_WITH_STATUS);
 	}
 
+	/* set diff algorithm */
+	options->xdl_opts |= diff_algorithm;
+
 	return 0;
 }
 
@@ -3528,6 +3552,17 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
 		DIFF_XDL_SET(options, PATIENCE_DIFF);
 	else if (!strcmp(arg, "--histogram"))
 		DIFF_XDL_SET(options, HISTOGRAM_DIFF);
+	else if ((argcount = parse_long_opt("diff-algorithm", av, &optarg))) {
+		int alg = diff_algorithm_parse(optarg);
+		if (alg < 0)
+			die("unknown algorithm: %s", optarg);
+		DIFF_XDL_CLR(options, NEED_MINIMAL);
+		DIFF_XDL_CLR(options, HISTOGRAM_DIFF);
+		DIFF_XDL_CLR(options, PATIENCE_DIFF);
+		options->xdl_opts |= alg;
+		return argcount;
+	}
+
 
 	/* flags options */
 	else if (!strcmp(arg, "--binary")) {
-- 
1.7.8.5

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]