Skip to content

Commit 4e218f5

Browse files
dschogitster
authored andcommitted
Smudge the files fed to external diff and textconv
When preparing temporary files for an external diff or textconv, it is easier on the external tools, especially when they are implemented using platform tools, if they are fed the input after convert_to_working_tree(). This fixes msysGit issue 177. Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a95148d commit 4e218f5

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

diff.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1948,24 +1948,31 @@ void diff_free_filespec_data(struct diff_filespec *s)
19481948
s->cnt_data = NULL;
19491949
}
19501950

1951-
static void prep_temp_blob(struct diff_tempfile *temp,
1951+
static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
19521952
void *blob,
19531953
unsigned long size,
19541954
const unsigned char *sha1,
19551955
int mode)
19561956
{
19571957
int fd;
1958+
struct strbuf buf = STRBUF_INIT;
19581959

19591960
fd = git_mkstemp(temp->tmp_path, PATH_MAX, ".diff_XXXXXX");
19601961
if (fd < 0)
19611962
die("unable to create temp-file: %s", strerror(errno));
1963+
if (convert_to_working_tree(path,
1964+
(const char *)blob, (size_t)size, &buf)) {
1965+
blob = buf.buf;
1966+
size = buf.len;
1967+
}
19621968
if (write_in_full(fd, blob, size) != size)
19631969
die("unable to write temp-file");
19641970
close(fd);
19651971
temp->name = temp->tmp_path;
19661972
strcpy(temp->hex, sha1_to_hex(sha1));
19671973
temp->hex[40] = 0;
19681974
sprintf(temp->mode, "%06o", mode);
1975+
strbuf_release(&buf);
19691976
}
19701977

19711978
static struct diff_tempfile *prepare_temp_file(const char *name,
@@ -2006,7 +2013,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
20062013
die("readlink(%s)", name);
20072014
if (ret == sizeof(buf))
20082015
die("symlink too long: %s", name);
2009-
prep_temp_blob(temp, buf, ret,
2016+
prep_temp_blob(name, temp, buf, ret,
20102017
(one->sha1_valid ?
20112018
one->sha1 : null_sha1),
20122019
(one->sha1_valid ?
@@ -2032,7 +2039,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
20322039
else {
20332040
if (diff_populate_filespec(one, 0))
20342041
die("cannot read data blob for %s", one->path);
2035-
prep_temp_blob(temp, one->data, one->size,
2042+
prep_temp_blob(name, temp, one->data, one->size,
20362043
one->sha1, one->mode);
20372044
}
20382045
return temp;

t/t4020-diff-external.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,20 @@ test_expect_success 'GIT_EXTERNAL_DIFF with more than one changed files' '
136136
GIT_EXTERNAL_DIFF=echo git diff
137137
'
138138

139+
echo "#!$SHELL_PATH" >fake-diff.sh
140+
cat >> fake-diff.sh <<\EOF
141+
cat $2 >> crlfed.txt
142+
EOF
143+
chmod a+x fake-diff.sh
144+
145+
keep_only_cr () {
146+
tr -dc '\015'
147+
}
148+
149+
test_expect_success 'external diff with autocrlf = true' '
150+
git config core.autocrlf true &&
151+
GIT_EXTERNAL_DIFF=./fake-diff.sh git diff &&
152+
test $(wc -l < crlfed.txt) = $(cat crlfed.txt | keep_only_cr | wc -c)
153+
'
154+
139155
test_done

0 commit comments

Comments
 (0)