Subject: Re: git-archive and core.eol

From: René Scharfe <[email-masked]>
Date: Sat, 08 Jan 2011 14:35:55 +0100

Am 15.12.2010 23:32, schrieb Erik Faye-Lund:
> I recently tried the following on Windows:
> 
> $ git init
> Initialized empty Git repository in c:/Users/kusma/test/.git/
> $ echo "foo
> bar" > test.txt
> $ git -c core.autocrlf=true add test.txt
> warning: LF will be replaced by CRLF in test.txt.
> The file will have its original line endings in your working directory.
> $ git commit -m.
>  1 files changed, 2 insertions(+), 0 deletions(-)
>  create mode 100644 test.txt
> $ git -c core.autocrlf=true -c core.eol=lf archive --format=tar HEAD > test.tar
> $ tar xvf test.tar
> $ od -c test.txt
> 0000000   f   o   o  \r  \n   b   a   r  \r  \n
> 0000012
> 
> Just to be sure, I checked this:
> 
> $ git show HEAD:test.txt | od -c
> 0000000   f   o   o  \n   b   a   r  \n
> 0000010
> 
> Yep, the file has LF in the repo, as expected... the warning from
> git-add is a bit confusing, but OK.
> 
> Hmm, so git-archive writes CRLF even if I said I wanted LF. But then I
> tried this on Linux:
> 
> $ git init
> Initialized empty Git repository in /home/kusma/src/test/.git/
> $ echo "foo
> bar" > test.txt
> $ git add test.txt
> $ git commit -m.
> [master (root-commit) c6f195e] .
>  1 files changed, 2 insertions(+), 0 deletions(-)
>  create mode 100644 test.txt
> $ git -c core.autocrlf=true -c core.eol=crlf archive --format=tar HEAD
>> test.tar
> $ tar xvf test.tar
> test.txt
> $ od -c test.txt
> 0000000   f   o   o  \r  \n   b   a   r  \r  \n
> 0000012
> 
> This leaves me a bit puzzled. On Linux, I can override the default
> new-line style CRLF for git-archive, but I can't override it to LF on
> Windows?
> 
> I expected it to work because sha1_file_to_archive calls
> convert_to_working_tree. I've tried stepping through the code, but I
> don't quite understand where it goes wrong. Or even how the code is
> supposed to work :P
> 
> Does anyone have any clue what's going on? I'm running with the
> current master, git version 1.7.3.3.585.g74f6e.

I can't seem to replicate this (1.7.4-rc1); see below for the test script
I tried to come up with.  It should test all combinations of the relevant
config variables and the text attribute.  I cheated by simply setting the
expectations to match the results on Linux; I didn't check if these are
indeed the correct results.  The test passes for me on MinGW, too, though.

Did I miss a variable or are some of the expectations wrong?

Thanks,
René

 t/t5002-archive-eol.sh |   86 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/t/t5002-archive-eol.sh b/t/t5002-archive-eol.sh
new file mode 100755
index 0000000..50f80f7
--- /dev/null
+++ b/t/t5002-archive-eol.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+test_description='git archive EOL tests'
+
+. ./test-lib.sh
+
+prepare() {
+	tfile="autocrlf_$1-eol_$2.tar"
+	dir="autocrlf_$1-eol_$2.d"
+	test_expect_success "archive with autocrlf=$1 eol=$2" "
+		git -c core.autocrlf=$1 -c core.eol=$2 archive HEAD >$tfile &&
+		(mkdir $dir && cd $dir && \"$TAR\" xf -) <$tfile
+	"
+}
+
+expect_success() {
+	file="autocrlf_$2-eol_$3.d/autocrlf_$1/$4"
+	desc="add autocrlf=$1, archive autocrlf=$2 eol=$3"
+	test_expect_success "$desc: $4 => $5" "test_cmp $5 $file"
+}
+
+test_expect_success 'setup' '
+	printf "1\\n2\\n" >lf &&
+	printf "1\\r\\n2\\r\\n" >crlf &&
+
+	echo "*.txt text" >.gitattributes &&
+	git add .gitattributes &&
+
+	mkdir autocrlf_false &&
+	cp lf crlf autocrlf_false/ &&
+	cp lf autocrlf_false/lf.txt &&
+	cp crlf autocrlf_false/crlf.txt &&
+	git -c core.autocrlf=false add autocrlf_false/ &&
+
+	mkdir autocrlf_true &&
+	cp lf crlf autocrlf_true/ &&
+	cp lf autocrlf_true/lf.txt &&
+	cp crlf autocrlf_true/crlf.txt &&
+	git -c core.autocrlf=true add autocrlf_true/ &&
+
+	git commit -m.
+'
+
+#	core.autocrlf	core.eol
+prepare	false		crlf
+prepare	true		crlf
+prepare	false		lf
+prepare	true		lf
+
+#		core.autocrlf	core.eol	original	expect
+#		(add)	(archive)
+expect_success	false	false	crlf		crlf		crlf
+expect_success	false	false	crlf		lf		lf
+expect_success	false	false	lf		crlf		crlf
+expect_success	false	false	lf		lf		lf
+expect_success	false	true	crlf		crlf		crlf
+expect_success	false	true	crlf		lf		crlf
+expect_success	false	true	lf		crlf		crlf
+expect_success	false	true	lf		lf		crlf
+expect_success	true	false	crlf		crlf		lf
+expect_success	true	false	crlf		lf		lf
+expect_success	true	false	lf		crlf		lf
+expect_success	true	false	lf		lf		lf
+expect_success	true	true	crlf		crlf		crlf
+expect_success	true	true	crlf		lf		crlf
+expect_success	true	true	lf		crlf		crlf
+expect_success	true	true	lf		lf		crlf
+
+expect_success	false	false	crlf		crlf.txt	crlf
+expect_success	false	false	crlf		lf.txt		crlf
+expect_success	false	false	lf		crlf.txt	lf
+expect_success	false	false	lf		lf.txt		lf
+expect_success	false	true	crlf		crlf.txt	crlf
+expect_success	false	true	crlf		lf.txt		crlf
+expect_success	false	true	lf		crlf.txt	crlf
+expect_success	false	true	lf		lf.txt		crlf
+expect_success	true	false	crlf		crlf.txt	crlf
+expect_success	true	false	crlf		lf.txt		crlf
+expect_success	true	false	lf		crlf.txt	lf
+expect_success	true	false	lf		lf.txt		lf
+expect_success	true	true	crlf		crlf.txt	crlf
+expect_success	true	true	crlf		lf.txt		crlf
+expect_success	true	true	lf		crlf.txt	crlf
+expect_success	true	true	lf		lf.txt		crlf
+
+test_done