git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/3] diff: tweak a _copy_ of diff_options with word-diff

From
Thomas Rast <trast@student.ethz.ch>
Date
Mar 14, 2012, 18:24 UTC
Message-ID
<b7d30afe65910ffe614a894db65386477778c4da.1331749299.git.trast@student.ethz.ch>
In-Reply-To
<3bb99e938624ae674674b304c24c48b9dc05871b.1331749299.git.trast@student.ethz.ch>

When using word diff, the code sets the word_regex from various defaults if it was not set already. The problem is that it does this on the original diff_options, which will also be used in subsequent diffs.

This means that when the word_regex is not given on the command line, only the first diff for which a setting for word_regex (either from attributes or diff.wordRegex) ever takes effect. This value then propagates to the rest of the diff runs and in particular prevents further attribute lookups.

Fix the problem of changing diff state once and for all, by working with a _copy_ of the diff_options.

Noticed-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 diff.c                |    5 ++++-
 t/t4034-diff-words.sh |    2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/diff.c b/diff.c
index aac86d3..c6104b9 100644
--- a/diff.c
+++ b/diff.c
@@ -1010,11 +1010,13 @@ static const char *userdiff_word_regex(struct diff_filespec *one)
 }
 
 static void init_diff_words_data(struct emit_callback *ecbdata,
-				 struct diff_options *o,
+				 struct diff_options *orig_opts,
 				 struct diff_filespec *one,
 				 struct diff_filespec *two)
 {
 	int i;
+	struct diff_options *o = xmalloc(sizeof(struct diff_options));
+	memcpy(o, orig_opts, sizeof(struct diff_options));
 
 	ecbdata->diff_words =
 		xcalloc(1, sizeof(struct diff_words_data));
@@ -1054,6 +1056,7 @@ static void free_diff_words_data(struct emit_callback *ecbdata)
 {
 	if (ecbdata->diff_words) {
 		diff_words_flush(ecbdata);
+		free (ecbdata->diff_words->opt);
 		free (ecbdata->diff_words->minus.text.ptr);
 		free (ecbdata->diff_words->minus.orig);
 		free (ecbdata->diff_words->plus.text.ptr);
diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh
index 69e81f3..c04756e 100755
--- a/t/t4034-diff-words.sh
+++ b/t/t4034-diff-words.sh
@@ -364,7 +364,7 @@ test_expect_success 'setup history with two files' '
 	git commit -mmodified -a
 '
 
-test_expect_failure 'wordRegex for the first file does not apply to the second' '
+test_expect_success 'wordRegex for the first file does not apply to the second' '
 	echo "a diff=tex" >.gitattributes &&
 	git config diff.tex.wordRegex "[a-z]+|." &&
 	cat >expect <<-\EOF &&
-- 
1.7.10.rc0.286.gd2cb29
Previous: Junio C HamanoNext: Junio C Hamano
Message 4 of 10 in “Demonstrate a bug in --word-diff where diff.*.wordregex is "sticky"”
  1. 1/3 Demonstrate a bug in --word-diff where diff.*.wordregex is "sticky"Thomas Rast, Mar 14, 2012
  2. 2/3 diff: refactor the word-diff setup from builtin_diff_cmdThomas Rast, Mar 14, 2012
  3. Junio C HamanoMar 14, 2012
  4. 3/3 diff: tweak a _copy_ of diff_options with word-diffThomas Rast, Mar 14, 2012
  5. Junio C HamanoMar 14, 2012
  6. Junio C HamanoMar 14, 2012
  7. 1/3 Demonstrate a bug in --word-diff where diff.*.wordregex is "sticky"Johannes Sixt, Mar 14, 2012
  8. Stefano LattariniMar 14, 2012
  9. Junio C HamanoMar 14, 2012
  10. Johannes SixtMar 14, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.