git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] blame: make diff algorithm configurable
@ 2025-10-20 14:56 Antonin Delpeuch via GitGitGadget
  2025-10-20 16:05 ` Junio C Hamano
                   ` (2 more replies)
  0 siblings, 3 replies; 32+ messages in thread
From: Antonin Delpeuch via GitGitGadget @ 2025-10-20 14:56 UTC (permalink / raw)
  To: git; +Cc: Elijah Newren, Antonin Delpeuch, Antonin Delpeuch

From: Antonin Delpeuch <antonin@delpeuch.eu>

The diff algorithm used in 'git-blame(1)' can be configured using the
`--diff-algorithm` option or the `diff.algorithm` config variable.
Myers diff remains the default.

Signed-off-by: Antonin Delpeuch <antonin@delpeuch.eu>
---
    blame: make diff algorithm configurable
    
    There has been long-standing interest in changing the default diff
    algorithm to "histogram", and Git 3.0 was floated as a possible occasion
    for that: https://lore.kernel.org/git/xmqqed873vgn.fsf@gitster.g/
    
    As a preparation, it is worth making sure that the diff algorithm is
    configurable where useful. It can have significant impact on the output
    of the git-blame command, so I propose to make it configurable there
    too. I have followed the convention of other commands (such as git-diff)
    to introduce a --diff-algorithm option.
    
    I understand that this command is a user-facing (porcelain) one, so I
    think making it honor the diff.algorithm UI config variable is also
    appropriate. The git-blame command has a machine-readable format that
    can be enabled with --porcelain (which should be called --plumbing if
    you ask me) so I wonder if the diff.algorithm variable should still be
    honored in this case, as there could be the desire to keep it
    independent from UI config variables (similarly to git-merge-file, a
    plumbing command which doesn't honor diff.algorithm).
    
    If the general idea of this patch is judged worthwhile, I would be happy
    to add tests to demonstrate the impact of the diff algorithm on blame
    output.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2075%2Fwetneb%2Fblame_respects_diff_algorithm-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2075/wetneb/blame_respects_diff_algorithm-v1
Pull-Request: https://github.com/git/git/pull/2075

 Documentation/git-blame.adoc | 21 ++++++++++++++++++++
 builtin/blame.c              | 38 +++++++++++++++++++++++++++++++++++-
 2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-blame.adoc b/Documentation/git-blame.adoc
index e438d28625..4beb2df551 100644
--- a/Documentation/git-blame.adoc
+++ b/Documentation/git-blame.adoc
@@ -85,6 +85,27 @@ include::blame-options.adoc[]
 	Ignore whitespace when comparing the parent's version and
 	the child's to find where the lines came from.
 
+`--diff-algorithm=(patience|minimal|histogram|myers)`::
+	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".
+--
++
+For instance, if you configured the `diff.algorithm` variable to a
+non-default value and want to use the default one, then you
+have to use `--diff-algorithm=default` option.
+
 --abbrev=<n>::
 	Instead of using the default 7+1 hexadecimal digits as the
 	abbreviated object name, use <m>+1 digits, where <m> is at
diff --git a/builtin/blame.c b/builtin/blame.c
index 2703820258..177b606e81 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -779,6 +779,19 @@ static int git_blame_config(const char *var, const char *value,
 		}
 	}
 
+	if (!strcmp(var, "diff.algorithm")) {
+		long diff_algorithm;
+		if (!value)
+			return config_error_nonbool(var);
+		diff_algorithm = parse_algorithm_value(value);
+		if (diff_algorithm < 0)
+			return error(_("unknown value for config '%s': %s"),
+				     var, value);
+		xdl_opts &= ~XDF_DIFF_ALGORITHM_MASK;
+		xdl_opts |= diff_algorithm;
+		return 0;
+	}
+
 	if (git_diff_heuristic_config(var, value, cb) < 0)
 		return -1;
 	if (userdiff_config(var, value) < 0)
@@ -824,6 +837,26 @@ static int blame_move_callback(const struct option *option, const char *arg, int
 	return 0;
 }
 
+static int blame_diff_algorithm_callback(const struct option *option,
+					 const char *arg, int unset)
+{
+	int *opt = option->value;
+	long value = parse_algorithm_value(arg);
+
+	BUG_ON_OPT_NEG(unset);
+
+	if (value < 0)
+		return error(_("option diff-algorithm accepts \"myers\", "
+			       "\"minimal\", \"patience\" and \"histogram\""));
+
+	// ignore any previous --minimal setting, following git-diff's behavior
+	*opt &= ~XDF_NEED_MINIMAL;
+	*opt &= ~XDF_DIFF_ALGORITHM_MASK;
+	*opt |= value;
+
+	return 0;
+}
+
 static int is_a_rev(const char *name)
 {
 	struct object_id oid;
@@ -908,13 +941,16 @@ int cmd_blame(int argc,
 		OPT_BIT('f', "show-name", &output_option, N_("show original filename (Default: auto)"), OUTPUT_SHOW_NAME),
 		OPT_BIT('n', "show-number", &output_option, N_("show original linenumber (Default: off)"), OUTPUT_SHOW_NUMBER),
 		OPT_BIT('p', "porcelain", &output_option, N_("show in a format designed for machine consumption"), OUTPUT_PORCELAIN),
-		OPT_BIT(0, "line-porcelain", &output_option, N_("show porcelain format with per-line commit information"), OUTPUT_PORCELAIN|OUTPUT_LINE_PORCELAIN),
+		OPT_BIT(0, "line-porcelain", &output_option, N_("show porcelain format with per-line commit information"), OUTPUT_PORCELAIN | OUTPUT_LINE_PORCELAIN),
 		OPT_BIT('c', NULL, &output_option, N_("use the same output mode as git-annotate (Default: off)"), OUTPUT_ANNOTATE_COMPAT),
 		OPT_BIT('t', NULL, &output_option, N_("show raw timestamp (Default: off)"), OUTPUT_RAW_TIMESTAMP),
 		OPT_BIT('l', NULL, &output_option, N_("show long commit SHA1 (Default: off)"), OUTPUT_LONG_OBJECT_NAME),
 		OPT_BIT('s', NULL, &output_option, N_("suppress author name and timestamp (Default: off)"), OUTPUT_NO_AUTHOR),
 		OPT_BIT('e', "show-email", &output_option, N_("show author email instead of name (Default: off)"), OUTPUT_SHOW_EMAIL),
 		OPT_BIT('w', NULL, &xdl_opts, N_("ignore whitespace differences"), XDF_IGNORE_WHITESPACE),
+		OPT_CALLBACK_F(0, "diff-algorithm", &xdl_opts, N_("<algorithm>"),
+			       N_("choose a diff algorithm"),
+			       PARSE_OPT_NONEG, blame_diff_algorithm_callback),
 		OPT_STRING_LIST(0, "ignore-rev", &ignore_rev_list, N_("rev"), N_("ignore <rev> when blaming")),
 		OPT_STRING_LIST(0, "ignore-revs-file", &ignore_revs_file_list, N_("file"), N_("ignore revisions from <file>")),
 		OPT_BIT(0, "color-lines", &output_option, N_("color redundant metadata from previous line differently"), OUTPUT_COLOR_LINE),

base-commit: 4253630c6f07a4bdcc9aa62a50e26a4d466219d1
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2025-11-17 18:24 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-20 14:56 [PATCH] blame: make diff algorithm configurable Antonin Delpeuch via GitGitGadget
2025-10-20 16:05 ` Junio C Hamano
2025-10-22  9:37   ` Antonin Delpeuch
2025-10-22 20:39     ` Junio C Hamano
2025-10-23 16:03 ` Phillip Wood
2025-10-28 13:37 ` [PATCH v2] " Antonin Delpeuch via GitGitGadget
2025-10-28 15:22   ` Junio C Hamano
2025-10-28 16:00     ` Antonin Delpeuch
2025-10-28 21:14   ` [PATCH v3] " Antonin Delpeuch via GitGitGadget
2025-10-29 10:16     ` Phillip Wood
2025-10-29 18:46       ` Junio C Hamano
2025-10-30  9:22       ` Antonin Delpeuch
2025-10-30 10:47         ` Phillip Wood
2025-11-01 21:57     ` [PATCH v4 0/2] " Antonin Delpeuch via GitGitGadget
2025-11-01 21:57       ` [PATCH v4 1/2] xdiff: add 'minimal' to XDF_DIFF_ALGORITHM_MASK Antonin Delpeuch via GitGitGadget
2025-11-03 14:32         ` Phillip Wood
2025-11-01 21:57       ` [PATCH v4 2/2] blame: make diff algorithm configurable Antonin Delpeuch via GitGitGadget
2025-11-03 14:32         ` Phillip Wood
2025-11-03 16:15           ` Junio C Hamano
2025-11-06 20:29             ` Junio C Hamano
2025-11-06 22:41       ` [PATCH v5 0/2] " Antonin Delpeuch via GitGitGadget
2025-11-06 22:41         ` [PATCH v5 1/2] xdiff: add 'minimal' to XDF_DIFF_ALGORITHM_MASK Antonin Delpeuch via GitGitGadget
2025-11-07 15:52           ` Junio C Hamano
2025-11-06 22:41         ` [PATCH v5 2/2] blame: make diff algorithm configurable Antonin Delpeuch via GitGitGadget
2025-11-07 15:57           ` Junio C Hamano
2025-11-07 15:49         ` [PATCH v5 0/2] " Phillip Wood
2025-11-17  1:12           ` Junio C Hamano
2025-11-17  8:04         ` [PATCH v6 " Antonin Delpeuch via GitGitGadget
2025-11-17  8:04           ` [PATCH v6 1/2] xdiff: add 'minimal' to XDF_DIFF_ALGORITHM_MASK Antonin Delpeuch via GitGitGadget
2025-11-17  8:04           ` [PATCH v6 2/2] blame: make diff algorithm configurable Antonin Delpeuch via GitGitGadget
2025-11-17 14:13           ` [PATCH v6 0/2] " Phillip Wood
2025-11-17 18:24           ` Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).