Fix checkout of files with mixed line endings on text=auto eol=crlf

Add tests for files having been checked in with mixed LF and CR-LF
line endings, and then being checked out with text or text=auto and
eol=lf or eol=crlf. These test cases were missing, and thus commit
efd1cc05 missed that AutoCRLFOutputStream needs the same detection
as AutoLFOutputStream.

Fix AutoCRLFOutputStream to not convert line endings if the blob in
the repository contains CR-LF.

Bug: 575393
Change-Id: Id0c7ae772e282097e95fddcd3f1f9d82aae31e43
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java
index 2a553ce..673aa1e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java
@@ -83,7 +83,8 @@
 		testCheckout(TEXT_CRLF, AUTO_CRLF, "\r\n", "\r\n");
 		testCheckout(TEXT_CRLF, AUTO_CRLF, "\n\r", "\r\n\r");
 
-		testCheckout(TEXT_CRLF, AUTO_CRLF, "\n\r\n", "\r\n\r\n");
+		testCheckout(null, AUTO_CRLF, "\n\r\n", "\n\r\n");
+		testCheckout(TEXT_CRLF, null, "\n\r\n", "\r\n\r\n");
 		testCheckout(TEXT_CRLF, AUTO_CRLF, "\r\n\r", "\r\n\r");
 
 		testCheckout(TEXT_CRLF, AUTO_CRLF, "a\nb\n", "a\r\nb\r\n");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
index b943486..af8a58f 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
@@ -337,6 +337,34 @@
 				"first line\r\nsecond line\r\n", "f text=auto eol=crlf");
 	}
 
+	@Test
+	public void testCheckoutMixedAutoEolCrLf() throws Exception {
+		checkoutLineEndings("first line\nsecond line\r\n",
+				"first line\nsecond line\r\n", "f text=auto eol=crlf");
+	}
+
+	@Test
+	public void testCheckoutMixedAutoEolLf() throws Exception {
+		checkoutLineEndings("first line\nsecond line\r\n",
+				"first line\nsecond line\r\n", "f text=auto eol=lf");
+	}
+
+	@Test
+	public void testCheckoutMixedTextCrLf() throws Exception {
+		// Huh? Is this a bug in git? Both git 2.18.0 and git 2.33.0 do
+		// write the file with CRLF (and consequently report the file as
+		// modified in "git status" after check-out), however the CRLF in the
+		// repository is _not_ replaced by LF with eol=lf (see test below).
+		checkoutLineEndings("first line\nsecond line\r\n",
+				"first line\r\nsecond line\r\n", "f text eol=crlf");
+	}
+
+	@Test
+	public void testCheckoutMixedTextLf() throws Exception {
+		checkoutLineEndings("first line\nsecond line\r\nfoo",
+				"first line\nsecond line\r\nfoo", "f text eol=lf");
+	}
+
 	private DirCacheCheckout resetHard(RevCommit commit)
 			throws NoWorkTreeException,
 			CorruptObjectException, IOException {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoCRLFOutputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoCRLFOutputStreamTest.java
index 85ce538..db2f6da 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoCRLFOutputStreamTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoCRLFOutputStreamTest.java
@@ -34,7 +34,7 @@
 		assertNoCrLf("\r\n\r", "\n\r");
 		assertNoCrLf("\r\n\r\r", "\r\n\r\r");
 		assertNoCrLf("\r\n\r\n", "\r\n\r\n");
-		assertNoCrLf("\r\n\r\n\r", "\n\r\n\r");
+		assertNoCrLf("\n\r\n\r", "\n\r\n\r");
 		assertNoCrLf("\0\n", "\0\n");
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFOutputStream.java
index ea6b658..97fe01e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFOutputStream.java
@@ -137,6 +137,9 @@
 	private void decideMode() throws IOException {
 		if (detectBinary) {
 			isBinary = RawText.isBinary(binbuf, binbufcnt);
+			if (!isBinary) {
+				isBinary = RawText.isCrLfText(binbuf, binbufcnt);
+			}
 			detectBinary = false;
 		}
 		int cachedLen = binbufcnt;