summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2015-06-08 15:58:54 -0400
committerEdward Thomson <ethomson@microsoft.com>2015-06-22 12:00:19 -0400
commit47e9a6cb0573aa2190ddabadb94c0a89ae14ba52 (patch)
tree0fbc9f1160b0253e27a8f43d60fde316b746d9b0
parent71686ddca660a3544c5aa6d4a34d1d06c031f4f9 (diff)
downloadlibgit2-47e9a6cb0573aa2190ddabadb94c0a89ae14ba52.tar.gz
crlf: use statistics to control to workdir filter
Use statistics (like core git) to control the behavior of the to workdir CRLF filter.
-rw-r--r--src/crlf.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/src/crlf.c b/src/crlf.c
index b5d1dbf32..2fe8a5f55 100644
--- a/src/crlf.c
+++ b/src/crlf.c
@@ -224,16 +224,14 @@ line_ending_error:
static int crlf_apply_to_workdir(
struct crlf_attrs *ca, git_buf *to, const git_buf *from)
{
+ git_buf_text_stats stats;
const char *workdir_ending = NULL;
+ bool is_binary;
/* Empty file? Nothing to do. */
if (git_buf_len(from) == 0)
return 0;
- /* Don't filter binary files */
- if (git_buf_text_is_binary(from))
- return GIT_PASSTHROUGH;
-
/* Determine proper line ending */
workdir_ending = line_ending(ca);
if (!workdir_ending)
@@ -243,6 +241,29 @@ static int crlf_apply_to_workdir(
if (strcmp(workdir_ending, "\r\n") != 0)
return GIT_PASSTHROUGH;
+ /* If there are no LFs, or all LFs are part of a CRLF, nothing to do */
+ is_binary = git_buf_text_gather_stats(&stats, from, false);
+
+ if (stats.lf == 0 || stats.lf == stats.crlf)
+ return GIT_PASSTHROUGH;
+
+ if (ca->crlf_action == GIT_CRLF_AUTO ||
+ ca->crlf_action == GIT_CRLF_GUESS) {
+
+ /* If we have any existing CR or CRLF line endings, do nothing */
+ if (ca->crlf_action == GIT_CRLF_GUESS &&
+ stats.cr > 0 && stats.crlf > 0)
+ return GIT_PASSTHROUGH;
+
+ /* If we have bare CR characters, do nothing */
+ if (stats.cr != stats.crlf)
+ return GIT_PASSTHROUGH;
+
+ /* Don't filter binary files */
+ if (is_binary)
+ return GIT_PASSTHROUGH;
+ }
+
return git_buf_text_lf_to_crlf(to, from);
}