diff: tweak a _copy_ of diff_options with word-diff

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> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Thomas Rast committed Mar 14, 2012 at 19:24 UTC 6440d3417c1d51a20014d4b6fc6c59bacfa87dab
2 files changed +5 -2
diff.c
+4 -1
@@ -1008,11 +1008,13 @@ static const char *userdiff_word_regex(struct diff_filespec *one)
1008 }
1009
1010 static void init_diff_words_data(struct emit_callback *ecbdata,
1011 - struct diff_options *o,
1011 + struct diff_options *orig_opts,
1012 struct diff_filespec *one,
1013 struct diff_filespec *two)
1014 {
1015 int i;
1016 + struct diff_options *o = xmalloc(sizeof(struct diff_options));
1017 + memcpy(o, orig_opts, sizeof(struct diff_options));
1018
1019 ecbdata->diff_words =
1020 xcalloc(1, sizeof(struct diff_words_data));
@@ -1052,6 +1054,7 @@ static void free_diff_words_data(struct emit_callback *ecbdata)
1054 {
1055 if (ecbdata->diff_words) {
1056 diff_words_flush(ecbdata);
1057 + free (ecbdata->diff_words->opt);
1058 free (ecbdata->diff_words->minus.text.ptr);
1059 free (ecbdata->diff_words->minus.orig);
1060 free (ecbdata->diff_words->plus.text.ptr);
t/t4034-diff-words.sh
+1 -1
@@ -365,7 +365,7 @@ test_expect_success 'setup history with two files' '
365 git commit -mmodified -a
366 '
367
368 -test_expect_failure 'wordRegex for the first file does not apply to the second' '
368 +test_expect_success 'wordRegex for the first file does not apply to the second' '
369 echo "*.tex diff=tex" >.gitattributes &&
370 git config diff.tex.wordRegex "[a-z]+|." &&
371 cat >expect <<-\EOF &&