Commit 3ddd0d929d329c09c5bf37258b81c76b52c68c56

Carlos Martín Nieto 2014-06-24T17:55:15

Merge remote-tracking branch 'upstream/cmn/mixed-eol-passthrough'

diff --git a/src/buf_text.c b/src/buf_text.c
index 631feb3..8d2b141 100644
--- a/src/buf_text.c
+++ b/src/buf_text.c
@@ -123,9 +123,13 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
 
 	for (; next; scan = next + 1, next = memchr(scan, '\n', end - scan)) {
 		size_t copylen = next - scan;
-		/* don't convert existing \r\n to \r\r\n */
-		size_t extralen = (next > start && next[-1] == '\r') ? 1 : 2;
-		size_t needsize = tgt->size + copylen + extralen + 1;
+		size_t needsize = tgt->size + copylen + 2 + 1;
+
+		/* if we find mixed line endings, bail */
+		if (next > start && next[-1] == '\r') {
+			git_buf_free(tgt);
+			return GIT_PASSTHROUGH;
+		}
 
 		if (tgt->asize < needsize && git_buf_grow(tgt, needsize) < 0)
 			return -1;
@@ -134,8 +138,8 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
 			memcpy(tgt->ptr + tgt->size, scan, copylen);
 			tgt->size += copylen;
 		}
-		if (extralen == 2)
-			tgt->ptr[tgt->size++] = '\r';
+
+		tgt->ptr[tgt->size++] = '\r';
 		tgt->ptr[tgt->size++] = '\n';
 	}
 
diff --git a/src/buf_text.h b/src/buf_text.h
index 3ac9d14..e753a02 100644
--- a/src/buf_text.h
+++ b/src/buf_text.h
@@ -56,9 +56,10 @@ GIT_INLINE(int) git_buf_text_puts_escape_regex(git_buf *buf, const char *string)
 extern void git_buf_text_unescape(git_buf *buf);
 
 /**
- * Replace all \r\n with \n. Does not modify \r without trailing \n.
+ * Replace all \r\n with \n.
  *
- * @return 0 on success, -1 on memory error
+ * @return 0 on success, -1 on memory error, GIT_PASSTHROUGH if the
+ * source buffer has mixed line endings.
  */
 extern int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src);
 
diff --git a/tests/checkout/crlf.c b/tests/checkout/crlf.c
index 6b2c1b1..2c84a77 100644
--- a/tests/checkout/crlf.c
+++ b/tests/checkout/crlf.c
@@ -79,10 +79,7 @@ void test_checkout_crlf__more_lf_autocrlf_true(void)
 
 	git_checkout_head(g_repo, &opts);
 
-	if (GIT_EOL_NATIVE == GIT_EOL_LF)
-		check_file_contents("./crlf/more-lf", MORE_LF_TEXT_RAW);
-	else
-		check_file_contents("./crlf/more-lf", MORE_LF_TEXT_AS_CRLF);
+	check_file_contents("./crlf/more-lf", MORE_LF_TEXT_RAW);
 }
 
 void test_checkout_crlf__more_crlf_autocrlf_true(void)
@@ -94,10 +91,7 @@ void test_checkout_crlf__more_crlf_autocrlf_true(void)
 
 	git_checkout_head(g_repo, &opts);
 
-	if (GIT_EOL_NATIVE == GIT_EOL_LF)
-		check_file_contents("./crlf/more-crlf", MORE_CRLF_TEXT_RAW);
-	else
-		check_file_contents("./crlf/more-crlf", MORE_CRLF_TEXT_AS_CRLF);
+	check_file_contents("./crlf/more-crlf", MORE_CRLF_TEXT_RAW);
 }
 
 void test_checkout_crlf__all_crlf_autocrlf_true(void)
diff --git a/tests/core/buffer.c b/tests/core/buffer.c
index da5ec60..8310dea 100644
--- a/tests/core/buffer.c
+++ b/tests/core/buffer.c
@@ -1034,18 +1034,14 @@ void test_core_buffer__lf_and_crlf_conversions(void)
 
 	git_buf_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n");
 
-	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
-	check_buf("crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n", tgt);
-	check_buf(src.ptr, tgt);
+	cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
 
 	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
 	check_buf("crlf\ncrlf\ncrlf\ncrlf\n", tgt);
 
 	git_buf_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf");
 
-	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
-	check_buf("\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf", tgt);
-	check_buf(src.ptr, tgt);
+	cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
 
 	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
 	check_buf("\ncrlf\ncrlf\ncrlf\ncrlf\ncrlf", tgt);
@@ -1054,8 +1050,7 @@ void test_core_buffer__lf_and_crlf_conversions(void)
 
 	git_buf_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n");
 
-	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
-	check_buf("\r\nlf\r\nlf\r\ncrlf\r\nlf\r\nlf\r\ncrlf\r\n", tgt);
+	cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
 	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
 	check_buf("\nlf\nlf\ncrlf\nlf\nlf\ncrlf\n", tgt);
 
@@ -1063,8 +1058,7 @@ void test_core_buffer__lf_and_crlf_conversions(void)
 
 	git_buf_sets(&src, "\ncrlf\r\ncrlf\r\nlf\ncrlf\r\ncrlf");
 
-	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
-	check_buf("\r\ncrlf\r\ncrlf\r\nlf\r\ncrlf\r\ncrlf", tgt);
+	cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
 	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
 	check_buf("\ncrlf\ncrlf\nlf\ncrlf\ncrlf", tgt);
 
@@ -1072,8 +1066,7 @@ void test_core_buffer__lf_and_crlf_conversions(void)
 
 	git_buf_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r");
 
-	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
-	check_buf("\rcrlf\r\nlf\r\nlf\r\ncr\rcrlf\r\nlf\r\ncr\r", tgt);
+	cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
 	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
 	check_buf("\rcrlf\nlf\nlf\ncr\rcrlf\nlf\ncr\r", tgt);
 
@@ -1089,8 +1082,7 @@ void test_core_buffer__lf_and_crlf_conversions(void)
 	/* blob correspondence tests */
 
 	git_buf_sets(&src, ALL_CRLF_TEXT_RAW);
-	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
-	check_buf(ALL_CRLF_TEXT_AS_CRLF, tgt);
+	cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
 	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
 	check_buf(ALL_CRLF_TEXT_AS_LF, tgt);
 	git_buf_free(&src);
@@ -1105,16 +1097,14 @@ void test_core_buffer__lf_and_crlf_conversions(void)
 	git_buf_free(&tgt);
 
 	git_buf_sets(&src, MORE_CRLF_TEXT_RAW);
-	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
-	check_buf(MORE_CRLF_TEXT_AS_CRLF, tgt);
+	cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
 	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
 	check_buf(MORE_CRLF_TEXT_AS_LF, tgt);
 	git_buf_free(&src);
 	git_buf_free(&tgt);
 
 	git_buf_sets(&src, MORE_LF_TEXT_RAW);
-	cl_git_pass(git_buf_text_lf_to_crlf(&tgt, &src));
-	check_buf(MORE_LF_TEXT_AS_CRLF, tgt);
+	cl_git_fail_with(GIT_PASSTHROUGH, git_buf_text_lf_to_crlf(&tgt, &src));
 	cl_git_pass(git_buf_text_crlf_to_lf(&tgt, &src));
 	check_buf(MORE_LF_TEXT_AS_LF, tgt);
 	git_buf_free(&src);