Code

diff: tweak a _copy_ of diff_options with word-diff
authorThomas Rast <trast@student.ethz.ch>
Wed, 14 Mar 2012 18:24:09 +0000 (19:24 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 14 Mar 2012 21:41:20 +0000 (14:41 -0700)
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>
diff.c
t/t4034-diff-words.sh

diff --git a/diff.c b/diff.c
index 526f1980596887dff99b1236ce39a47b6bdb7215..349a61d588bf65616875be59e8a5d86f0b18dd4f 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1008,11 +1008,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));
@@ -1052,6 +1054,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);
index 310ace1b5d32658c0afb33f66d9aa78dd3e75c6e..30d42cb3bfd856a7d920119f1c4226c408a8f82f 100755 (executable)
@@ -365,7 +365,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 "*.tex diff=tex" >.gitattributes &&
        git config diff.tex.wordRegex "[a-z]+|." &&
        cat >expect <<-\EOF &&