diff options
author | Edward Thomson <ethomson@microsoft.com> | 2015-06-08 15:58:54 -0400 |
---|---|---|
committer | Edward Thomson <ethomson@microsoft.com> | 2015-06-22 12:00:19 -0400 |
commit | 47e9a6cb0573aa2190ddabadb94c0a89ae14ba52 (patch) | |
tree | 0fbc9f1160b0253e27a8f43d60fde316b746d9b0 | |
parent | 71686ddca660a3544c5aa6d4a34d1d06c031f4f9 (diff) | |
download | libgit2-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.c | 29 |
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); } |