Browse Source

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 <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Johannes Schindelin 16 years ago committed by Junio C Hamano
parent
commit
4e218f54b3
  1. 13
      diff.c
  2. 16
      t/t4020-diff-external.sh

13
diff.c

@ -1948,17 +1948,23 @@ void diff_free_filespec_data(struct diff_filespec *s)
s->cnt_data = NULL; s->cnt_data = NULL;
} }


static void prep_temp_blob(struct diff_tempfile *temp, static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
void *blob, void *blob,
unsigned long size, unsigned long size,
const unsigned char *sha1, const unsigned char *sha1,
int mode) int mode)
{ {
int fd; int fd;
struct strbuf buf = STRBUF_INIT;


fd = git_mkstemp(temp->tmp_path, PATH_MAX, ".diff_XXXXXX"); fd = git_mkstemp(temp->tmp_path, PATH_MAX, ".diff_XXXXXX");
if (fd < 0) if (fd < 0)
die("unable to create temp-file: %s", strerror(errno)); die("unable to create temp-file: %s", strerror(errno));
if (convert_to_working_tree(path,
(const char *)blob, (size_t)size, &buf)) {
blob = buf.buf;
size = buf.len;
}
if (write_in_full(fd, blob, size) != size) if (write_in_full(fd, blob, size) != size)
die("unable to write temp-file"); die("unable to write temp-file");
close(fd); close(fd);
@ -1966,6 +1972,7 @@ static void prep_temp_blob(struct diff_tempfile *temp,
strcpy(temp->hex, sha1_to_hex(sha1)); strcpy(temp->hex, sha1_to_hex(sha1));
temp->hex[40] = 0; temp->hex[40] = 0;
sprintf(temp->mode, "%06o", mode); sprintf(temp->mode, "%06o", mode);
strbuf_release(&buf);
} }


static struct diff_tempfile *prepare_temp_file(const char *name, static struct diff_tempfile *prepare_temp_file(const char *name,
@ -2006,7 +2013,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
die("readlink(%s)", name); die("readlink(%s)", name);
if (ret == sizeof(buf)) if (ret == sizeof(buf))
die("symlink too long: %s", name); die("symlink too long: %s", name);
prep_temp_blob(temp, buf, ret, prep_temp_blob(name, temp, buf, ret,
(one->sha1_valid ? (one->sha1_valid ?
one->sha1 : null_sha1), one->sha1 : null_sha1),
(one->sha1_valid ? (one->sha1_valid ?
@ -2032,7 +2039,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
else { else {
if (diff_populate_filespec(one, 0)) if (diff_populate_filespec(one, 0))
die("cannot read data blob for %s", one->path); die("cannot read data blob for %s", one->path);
prep_temp_blob(temp, one->data, one->size, prep_temp_blob(name, temp, one->data, one->size,
one->sha1, one->mode); one->sha1, one->mode);
} }
return temp; return temp;

16
t/t4020-diff-external.sh

@ -136,4 +136,20 @@ test_expect_success 'GIT_EXTERNAL_DIFF with more than one changed files' '
GIT_EXTERNAL_DIFF=echo git diff GIT_EXTERNAL_DIFF=echo git diff
' '


echo "#!$SHELL_PATH" >fake-diff.sh
cat >> fake-diff.sh <<\EOF
cat $2 >> crlfed.txt
EOF
chmod a+x fake-diff.sh

keep_only_cr () {
tr -dc '\015'
}

test_expect_success 'external diff with autocrlf = true' '
git config core.autocrlf true &&
GIT_EXTERNAL_DIFF=./fake-diff.sh git diff &&
test $(wc -l < crlfed.txt) = $(cat crlfed.txt | keep_only_cr | wc -c)
'

test_done test_done

Loading…
Cancel
Save