Merge branch 'tr/maint-word-diff-regex-sticky'
The regexp configured with wordregex was incorrectly reused across files. By Thomas Rast (2) and Johannes Sixt (1) * tr/maint-word-diff-regex-sticky: diff: tweak a _copy_ of diff_options with word-diff diff: refactor the word-diff setup from builtin_diff_cmd t4034: diff.*.wordregex should not be "sticky" in --word-diff
This commit is contained in:
commit
3bec29bb07
122
diff.c
122
diff.c
@ -989,10 +989,74 @@ static void diff_words_flush(struct emit_callback *ecbdata)
|
|||||||
diff_words_show(ecbdata->diff_words);
|
diff_words_show(ecbdata->diff_words);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void diff_filespec_load_driver(struct diff_filespec *one)
|
||||||
|
{
|
||||||
|
/* Use already-loaded driver */
|
||||||
|
if (one->driver)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (S_ISREG(one->mode))
|
||||||
|
one->driver = userdiff_find_by_path(one->path);
|
||||||
|
|
||||||
|
/* Fallback to default settings */
|
||||||
|
if (!one->driver)
|
||||||
|
one->driver = userdiff_find_by_name("default");
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *userdiff_word_regex(struct diff_filespec *one)
|
||||||
|
{
|
||||||
|
diff_filespec_load_driver(one);
|
||||||
|
return one->driver->word_regex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_diff_words_data(struct emit_callback *ecbdata,
|
||||||
|
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));
|
||||||
|
ecbdata->diff_words->type = o->word_diff;
|
||||||
|
ecbdata->diff_words->opt = o;
|
||||||
|
if (!o->word_regex)
|
||||||
|
o->word_regex = userdiff_word_regex(one);
|
||||||
|
if (!o->word_regex)
|
||||||
|
o->word_regex = userdiff_word_regex(two);
|
||||||
|
if (!o->word_regex)
|
||||||
|
o->word_regex = diff_word_regex_cfg;
|
||||||
|
if (o->word_regex) {
|
||||||
|
ecbdata->diff_words->word_regex = (regex_t *)
|
||||||
|
xmalloc(sizeof(regex_t));
|
||||||
|
if (regcomp(ecbdata->diff_words->word_regex,
|
||||||
|
o->word_regex,
|
||||||
|
REG_EXTENDED | REG_NEWLINE))
|
||||||
|
die ("Invalid regular expression: %s",
|
||||||
|
o->word_regex);
|
||||||
|
}
|
||||||
|
for (i = 0; i < ARRAY_SIZE(diff_words_styles); i++) {
|
||||||
|
if (o->word_diff == diff_words_styles[i].type) {
|
||||||
|
ecbdata->diff_words->style =
|
||||||
|
&diff_words_styles[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (want_color(o->use_color)) {
|
||||||
|
struct diff_words_style *st = ecbdata->diff_words->style;
|
||||||
|
st->old.color = diff_get_color_opt(o, DIFF_FILE_OLD);
|
||||||
|
st->new.color = diff_get_color_opt(o, DIFF_FILE_NEW);
|
||||||
|
st->ctx.color = diff_get_color_opt(o, DIFF_PLAIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void free_diff_words_data(struct emit_callback *ecbdata)
|
static void free_diff_words_data(struct emit_callback *ecbdata)
|
||||||
{
|
{
|
||||||
if (ecbdata->diff_words) {
|
if (ecbdata->diff_words) {
|
||||||
diff_words_flush(ecbdata);
|
diff_words_flush(ecbdata);
|
||||||
|
free (ecbdata->diff_words->opt);
|
||||||
free (ecbdata->diff_words->minus.text.ptr);
|
free (ecbdata->diff_words->minus.text.ptr);
|
||||||
free (ecbdata->diff_words->minus.orig);
|
free (ecbdata->diff_words->minus.orig);
|
||||||
free (ecbdata->diff_words->plus.text.ptr);
|
free (ecbdata->diff_words->plus.text.ptr);
|
||||||
@ -2061,20 +2125,6 @@ static void emit_binary_diff(FILE *file, mmfile_t *one, mmfile_t *two, char *pre
|
|||||||
emit_binary_diff_body(file, two, one, prefix);
|
emit_binary_diff_body(file, two, one, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void diff_filespec_load_driver(struct diff_filespec *one)
|
|
||||||
{
|
|
||||||
/* Use already-loaded driver */
|
|
||||||
if (one->driver)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (S_ISREG(one->mode))
|
|
||||||
one->driver = userdiff_find_by_path(one->path);
|
|
||||||
|
|
||||||
/* Fallback to default settings */
|
|
||||||
if (!one->driver)
|
|
||||||
one->driver = userdiff_find_by_name("default");
|
|
||||||
}
|
|
||||||
|
|
||||||
int diff_filespec_is_binary(struct diff_filespec *one)
|
int diff_filespec_is_binary(struct diff_filespec *one)
|
||||||
{
|
{
|
||||||
if (one->is_binary == -1) {
|
if (one->is_binary == -1) {
|
||||||
@ -2100,12 +2150,6 @@ static const struct userdiff_funcname *diff_funcname_pattern(struct diff_filespe
|
|||||||
return one->driver->funcname.pattern ? &one->driver->funcname : NULL;
|
return one->driver->funcname.pattern ? &one->driver->funcname : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *userdiff_word_regex(struct diff_filespec *one)
|
|
||||||
{
|
|
||||||
diff_filespec_load_driver(one);
|
|
||||||
return one->driver->word_regex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b)
|
void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b)
|
||||||
{
|
{
|
||||||
if (!options->a_prefix)
|
if (!options->a_prefix)
|
||||||
@ -2292,42 +2336,8 @@ static void builtin_diff(const char *name_a,
|
|||||||
xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
|
xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
|
||||||
else if (!prefixcmp(diffopts, "-u"))
|
else if (!prefixcmp(diffopts, "-u"))
|
||||||
xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
|
xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
|
||||||
if (o->word_diff) {
|
if (o->word_diff)
|
||||||
int i;
|
init_diff_words_data(&ecbdata, o, one, two);
|
||||||
|
|
||||||
ecbdata.diff_words =
|
|
||||||
xcalloc(1, sizeof(struct diff_words_data));
|
|
||||||
ecbdata.diff_words->type = o->word_diff;
|
|
||||||
ecbdata.diff_words->opt = o;
|
|
||||||
if (!o->word_regex)
|
|
||||||
o->word_regex = userdiff_word_regex(one);
|
|
||||||
if (!o->word_regex)
|
|
||||||
o->word_regex = userdiff_word_regex(two);
|
|
||||||
if (!o->word_regex)
|
|
||||||
o->word_regex = diff_word_regex_cfg;
|
|
||||||
if (o->word_regex) {
|
|
||||||
ecbdata.diff_words->word_regex = (regex_t *)
|
|
||||||
xmalloc(sizeof(regex_t));
|
|
||||||
if (regcomp(ecbdata.diff_words->word_regex,
|
|
||||||
o->word_regex,
|
|
||||||
REG_EXTENDED | REG_NEWLINE))
|
|
||||||
die ("Invalid regular expression: %s",
|
|
||||||
o->word_regex);
|
|
||||||
}
|
|
||||||
for (i = 0; i < ARRAY_SIZE(diff_words_styles); i++) {
|
|
||||||
if (o->word_diff == diff_words_styles[i].type) {
|
|
||||||
ecbdata.diff_words->style =
|
|
||||||
&diff_words_styles[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (want_color(o->use_color)) {
|
|
||||||
struct diff_words_style *st = ecbdata.diff_words->style;
|
|
||||||
st->old.color = diff_get_color_opt(o, DIFF_FILE_OLD);
|
|
||||||
st->new.color = diff_get_color_opt(o, DIFF_FILE_NEW);
|
|
||||||
st->ctx.color = diff_get_color_opt(o, DIFF_PLAIN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
|
xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
|
||||||
&xpp, &xecfg);
|
&xpp, &xecfg);
|
||||||
if (o->word_diff)
|
if (o->word_diff)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
test_description='word diff colors'
|
test_description='word diff colors'
|
||||||
|
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
. "$TEST_DIRECTORY"/diff-lib.sh
|
||||||
|
|
||||||
cat >pre.simple <<-\EOF
|
cat >pre.simple <<-\EOF
|
||||||
h(4)
|
h(4)
|
||||||
@ -293,6 +294,10 @@ test_expect_success '--word-diff=none' '
|
|||||||
word_diff --word-diff=plain --word-diff=none
|
word_diff --word-diff=plain --word-diff=none
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'unset default driver' '
|
||||||
|
test_unconfig diff.wordregex
|
||||||
|
'
|
||||||
|
|
||||||
test_language_driver bibtex
|
test_language_driver bibtex
|
||||||
test_language_driver cpp
|
test_language_driver cpp
|
||||||
test_language_driver csharp
|
test_language_driver csharp
|
||||||
@ -348,4 +353,35 @@ test_expect_success 'word-diff with no newline at EOF' '
|
|||||||
word_diff --word-diff=plain
|
word_diff --word-diff=plain
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'setup history with two files' '
|
||||||
|
echo "a b; c" >a.tex &&
|
||||||
|
echo "a b; c" >z.txt &&
|
||||||
|
git add a.tex z.txt &&
|
||||||
|
git commit -minitial &&
|
||||||
|
|
||||||
|
# modify both
|
||||||
|
echo "a bx; c" >a.tex &&
|
||||||
|
echo "a bx; c" >z.txt &&
|
||||||
|
git commit -mmodified -a
|
||||||
|
'
|
||||||
|
|
||||||
|
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 &&
|
||||||
|
diff --git a/a.tex b/a.tex
|
||||||
|
--- a/a.tex
|
||||||
|
+++ b/a.tex
|
||||||
|
@@ -1 +1 @@
|
||||||
|
a [-b-]{+bx+}; c
|
||||||
|
diff --git a/z.txt b/z.txt
|
||||||
|
--- a/z.txt
|
||||||
|
+++ b/z.txt
|
||||||
|
@@ -1 +1 @@
|
||||||
|
a [-b;-]{+bx;+} c
|
||||||
|
EOF
|
||||||
|
git diff --word-diff HEAD~ >actual &&
|
||||||
|
compare_diff_patch expect actual
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user