mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-11 11:46:04 +00:00
crlf: pass-through mixed EOL buffers from LF->CRLF
When checking out files, we're performing conversion into the user's native line endings, but we only want to do it for files which have consistent line endings. Refuse to perform the conversion for mixed-EOL files. The CRLF->LF filter is left as-is, as that conversion is considered to be normalization by git and should force a conversion of the line endings.
This commit is contained in:
parent
1589aa0c4d
commit
5a76ad35aa
@ -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';
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user