git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] Respect core.autocrlf when preparing temporary files for external diff

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Mar 21, 2009, 11:42 UTC
Message-ID
<8cb424b16f21164ddc26d0be3f6f7727254b3506.1237635609u.git.johannes.schindelin@gmx.de>
In-Reply-To
<cover.1237635609u.git.johannes.schindelin@gmx.de>

When preparing temporary files for an external diff, the files should be handled as if they were worktree files.

This makes things consistent for the case when one side of the diff was found in the current working directory (and therefore creating a temporary file could be avoided altogether).

This fixes msysGit issue 177.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 diff.c                   |   13 ++++++++++---
 t/t4020-diff-external.sh |   16 ++++++++++++++++
 2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/diff.c b/diff.c
index 75d9fab..699ae6a 100644
--- a/diff.c
+++ b/diff.c
@@ -1946,17 +1946,23 @@ void diff_free_filespec_data(struct diff_filespec *s)
 	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,
 			   unsigned long size,
 			   const unsigned char *sha1,
 			   int mode)
 {
 	int fd;
+	struct strbuf buf = STRBUF_INIT;
 
 	fd = git_mkstemp(temp->tmp_path, PATH_MAX, ".diff_XXXXXX");
 	if (fd < 0)
 		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)
 		die("unable to write temp-file");
 	close(fd);
@@ -1964,6 +1970,7 @@ static void prep_temp_blob(struct diff_tempfile *temp,
 	strcpy(temp->hex, sha1_to_hex(sha1));
 	temp->hex[40] = 0;
 	sprintf(temp->mode, "%06o", mode);
+	strbuf_release(&buf);
 }
 
 static struct diff_tempfile *prepare_temp_file(const char *name,
@@ -2004,7 +2011,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
 				die("readlink(%s)", name);
 			if (ret == sizeof(buf))
 				die("symlink too long: %s", name);
-			prep_temp_blob(temp, buf, ret,
+			prep_temp_blob(name, temp, buf, ret,
 				       (one->sha1_valid ?
 					one->sha1 : null_sha1),
 				       (one->sha1_valid ?
@@ -2030,7 +2037,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
 	else {
 		if (diff_populate_filespec(one, 0))
 			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);
 	}
 	return temp;
diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh
index 281680d..f8c99f1 100755
--- a/t/t4020-diff-external.sh
+++ b/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
 '
 
+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
-- 
1.6.2.1.493.g67cf3
Next: Michael J Gruber
Message 1 of 14 in “Respect core.autocrlf when preparing temporary files for external diff”
  1. Respect core.autocrlf when preparing temporary files for external diffJohannes Schindelin, Mar 21, 2009
  2. Michael J GruberMar 21, 2009
  3. Junio C HamanoMar 21, 2009
  4. Johannes SchindelinMar 21, 2009
  5. Junio C HamanoMar 22, 2009
  6. Junio C HamanoMar 22, 2009
  7. Jeff KingMar 22, 2009
  8. Junio C HamanoMar 22, 2009
  9. Jeff KingMar 22, 2009
  10. Sebastian SchuberthMar 22, 2009
  11. Junio C HamanoMar 22, 2009
  12. Sebastian SchuberthMar 22, 2009
  13. Junio C HamanoMar 22, 2009
  14. Junio C HamanoMar 23, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.