diff --git a/combine-diff.c b/combine-diff.c
index 655fa89..8056fc3 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -8,7 +8,7 @@
#include "log-tree.h"
#include "refs.h"
-static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent)
+static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent, int textconv)
{
struct diff_queue_struct *q = &diff_queued_diff;
struct combine_diff_path *p;@@ -34,9 +34,13 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
hashcpy(p->sha1, q->queue[i]->two->sha1);
p->mode = q->queue[i]->two->mode;
+ if (textconv)
+ p->textconv = get_textconv(q->queue[i]->two);
hashcpy(p->parent[n].sha1, q->queue[i]->one->sha1);
p->parent[n].mode = q->queue[i]->one->mode;
p->parent[n].status = q->queue[i]->status;
+ if (textconv)
+ p->parent[n].textconv = get_textconv(q->queue[i]->one);
*tail = p;
tail = &p->next;
}
@@ -60,6 +64,8 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
hashcpy(p->parent[n].sha1, q->queue[i]->one->sha1);
p->parent[n].mode = q->queue[i]->one->mode;
p->parent[n].status = q->queue[i]->status;
+ if (textconv)
+ p->parent[n].textconv = get_textconv(q->queue[i]->one);
break;
}
}
@@ -201,8 +207,8 @@ static void consume_line(void *state_, char *line, unsigned long len)
}
}
-static void combine_diff(const unsigned char *parent, unsigned int mode,
- mmfile_t *result_file,
+static void combine_diff(const char *path, const unsigned char *parent, unsigned int mode,
+ struct userdiff_driver *textconv, mmfile_t *result_file,
struct sline *sline, unsigned int cnt, int n,
int num_parent, int result_deleted)
{@@ -212,13 +218,13 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
xdemitconf_t xecfg;
mmfile_t parent_file;
struct combine_diff_state state;
- unsigned long sz;
+ struct diff_filespec *df = alloc_filespec(path);
if (result_deleted)
return; /* result deleted */
- parent_file.ptr = grab_blob(parent, mode, &sz);
- parent_file.size = sz;
+ fill_filespec(df, parent, mode);
+ parent_file.size = fill_textconv(textconv, df, &parent_file.ptr);
memset(&xpp, 0, sizeof(xpp));
xpp.flags = 0;
memset(&xecfg, 0, sizeof(xecfg));
@@ -777,6 +783,12 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
close(fd);
}
+ if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) && elem->textconv) {
+ struct diff_filespec *df = alloc_filespec(elem->path);
+ fill_filespec(df, elem->sha1, elem->mode);
+ result_size = fill_textconv(elem->textconv, df, &result);
+ }
+
for (cnt = 0, cp = result; cp < result + result_size; cp++) {
if (*cp == '\n')
cnt++;@@ -821,8 +833,10 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
}
}
if (i <= j)
- combine_diff(elem->parent[i].sha1,
+ combine_diff(elem->path,
+ elem->parent[i].sha1,
elem->parent[i].mode,
+ elem->parent[i].textconv,
&result_file, sline,
cnt, i, num_parent, result_deleted);
if (elem->parent[i].mode != elem->mode)
@@ -1001,7 +1015,7 @@ void diff_tree_combined(const unsigned char *sha1,
diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_tree_sha1(parent[i], sha1, "", &diffopts);
diffcore_std(&diffopts);
- paths = intersect_paths(paths, i, num_parent);
+ paths = intersect_paths(paths, i, num_parent, DIFF_OPT_TST(opt, ALLOW_TEXTCONV));
if (show_log_first && i == 0) {
show_log(rev);diff --git a/diff.h b/diff.h
index 007a055..4ca6b84 100644
--- a/diff.h
+++ b/diff.h
@@ -176,10 +176,12 @@ struct combine_diff_path {
char *path;
unsigned int mode;
unsigned char sha1[20];
+ struct userdiff_driver *textconv;
struct combine_diff_parent {
char status;
unsigned int mode;
unsigned char sha1[20];
+ struct userdiff_driver *textconv;
} parent[FLEX_ARRAY];
};
#define combine_diff_path_size(n, l) \diff --git a/t/t4046-diff-textconv-merge.sh b/t/t4046-diff-textconv-merge.sh
new file mode 100755
index 0000000..8420bb6
--- /dev/null
+++ b/t/t4046-diff-textconv-merge.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+
+test_description='combined and merge diff uses textconv'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit one file &&
+ test_commit two file &&
+ git checkout -b other HEAD^ &&
+ test_commit three file &&
+ test_must_fail git merge master &&
+ echo resolved >file &&
+ echo "file diff=upcase" >.gitattributes &&
+ git config diff.upcase.textconv "tr a-z A-Z <"
+'
+
+cat >expect <<'EOF'
+diff --combined file
+index 2bdf67a,f719efd..0000000
+--- a/file
++++ b/file
+@@@ -1,1 -1,1 +1,1 @@@
+- THREE
+ -TWO
+++RESOLVED
+EOF
+test_expect_success 'diff -c uses textconv' '
+ git diff -c >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+diff --git a/file b/file
+index 2bdf67a..0000000 100644
+--- a/file
++++ b/file
+@@ -1 +1 @@
+-THREE
++RESOLVED
+
+diff --git a/file b/file
+index f719efd..0000000 100644
+--- a/file
++++ b/file
+@@ -1 +1 @@
+-TWO
++RESOLVED
+EOF
+test_expect_success 'diff -m uses textconv' '
+ git diff -m >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+Merge branch 'master' into other
+
+diff --combined file
+index 2bdf67a,f719efd..2ab19ae
+--- a/file
++++ b/file
+@@@ -1,1 -1,1 +1,1 @@@
+- THREE
+ -TWO
+++RESOLVED
+EOF
+test_expect_success 'show -c uses textconv' '
+ git commit -a &&
+ git show --format=%s -c >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+Merge branch 'master' into other
+
+diff --git a/file b/file
+index 2bdf67a..2ab19ae 100644
+--- a/file
++++ b/file
+@@ -1 +1 @@
+-THREE
++RESOLVED
+Merge branch 'master' into other
+
+diff --git a/file b/file
+index f719efd..2ab19ae 100644
+--- a/file
++++ b/file
+@@ -1 +1 @@
+-TWO
++RESOLVED
+EOF
+test_expect_success 'show -m uses textconv' '
+ git show --format=%s -m >actual &&
+ test_cmp expect actual
+'
+
+test_done
--
1.7.5.rc1.312.g1936c