summaryrefslogtreecommitdiff
path: root/convert.c
diff options
context:
space:
mode:
Diffstat (limited to 'convert.c')
-rw-r--r--convert.c97
1 files changed, 57 insertions, 40 deletions
diff --git a/convert.c b/convert.c
index 67d69b5..077f5e6 100644
--- a/convert.c
+++ b/convert.c
@@ -189,33 +189,25 @@ static enum eol output_eol(enum crlf_action crlf_action)
}
static void check_safe_crlf(const char *path, enum crlf_action crlf_action,
- struct text_stat *stats, enum safe_crlf checksafe)
+ struct text_stat *old_stats, struct text_stat *new_stats,
+ enum safe_crlf checksafe)
{
- if (!checksafe)
- return;
-
- if (output_eol(crlf_action) == EOL_LF) {
+ if (old_stats->crlf && !new_stats->crlf ) {
/*
- * CRLFs would not be restored by checkout:
- * check if we'd remove CRLFs
+ * CRLFs would not be restored by checkout
*/
- if (stats->crlf) {
- if (checksafe == SAFE_CRLF_WARN)
- warning("CRLF will be replaced by LF in %s.\nThe file will have its original line endings in your working directory.", path);
- else /* i.e. SAFE_CRLF_FAIL */
- die("CRLF would be replaced by LF in %s.", path);
- }
- } else if (output_eol(crlf_action) == EOL_CRLF) {
+ if (checksafe == SAFE_CRLF_WARN)
+ warning("CRLF will be replaced by LF in %s.\nThe file will have its original line endings in your working directory.", path);
+ else /* i.e. SAFE_CRLF_FAIL */
+ die("CRLF would be replaced by LF in %s.", path);
+ } else if (old_stats->lonelf && !new_stats->lonelf ) {
/*
- * CRLFs would be added by checkout:
- * check if we have "naked" LFs
+ * CRLFs would be added by checkout
*/
- if (stats->lonelf) {
- if (checksafe == SAFE_CRLF_WARN)
- warning("LF will be replaced by CRLF in %s.\nThe file will have its original line endings in your working directory.", path);
- else /* i.e. SAFE_CRLF_FAIL */
- die("LF would be replaced by CRLF in %s", path);
- }
+ if (checksafe == SAFE_CRLF_WARN)
+ warning("LF will be replaced by CRLF in %s.\nThe file will have its original line endings in your working directory.", path);
+ else /* i.e. SAFE_CRLF_FAIL */
+ die("LF would be replaced by CRLF in %s", path);
}
}
@@ -233,12 +225,35 @@ static int has_cr_in_index(const char *path)
return has_cr;
}
+static int will_convert_lf_to_crlf(size_t len, struct text_stat *stats,
+ enum crlf_action crlf_action)
+{
+ if (output_eol(crlf_action) != EOL_CRLF)
+ return 0;
+ /* No "naked" LF? Nothing to convert, regardless. */
+ if (!stats->lonelf)
+ return 0;
+
+ if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
+ /* If we have any CR or CRLF line endings, we do not touch it */
+ /* This is the new safer autocrlf-handling */
+ if (stats->lonecr || stats->crlf)
+ return 0;
+
+ if (convert_is_binary(len, stats))
+ return 0;
+ }
+ return 1;
+
+}
+
static int crlf_to_git(const char *path, const char *src, size_t len,
struct strbuf *buf,
enum crlf_action crlf_action, enum safe_crlf checksafe)
{
struct text_stat stats;
char *dst;
+ int convert_crlf_into_lf;
if (crlf_action == CRLF_BINARY ||
(src && !len))
@@ -252,6 +267,8 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
return 1;
gather_stats(src, len, &stats);
+ /* Optimization: No CRLF? Nothing to convert, regardless. */
+ convert_crlf_into_lf = !!stats.crlf;
if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
if (convert_is_binary(len, &stats))
@@ -263,12 +280,24 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
if (checksafe == SAFE_CRLF_RENORMALIZE)
checksafe = SAFE_CRLF_FALSE;
else if (has_cr_in_index(path))
- return 0;
+ convert_crlf_into_lf = 0;
}
- check_safe_crlf(path, crlf_action, &stats, checksafe);
-
- /* Optimization: No CRLF? Nothing to convert, regardless. */
- if (!stats.crlf)
+ if (checksafe && len) {
+ struct text_stat new_stats;
+ memcpy(&new_stats, &stats, sizeof(new_stats));
+ /* simulate "git add" */
+ if (convert_crlf_into_lf) {
+ new_stats.lonelf += new_stats.crlf;
+ new_stats.crlf = 0;
+ }
+ /* simulate "git checkout" */
+ if (will_convert_lf_to_crlf(len, &new_stats, crlf_action)) {
+ new_stats.crlf += new_stats.lonelf;
+ new_stats.lonelf = 0;
+ }
+ check_safe_crlf(path, crlf_action, &stats, &new_stats, checksafe);
+ }
+ if (!convert_crlf_into_lf)
return 0;
/*
@@ -314,21 +343,9 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len,
return 0;
gather_stats(src, len, &stats);
-
- /* No "naked" LF? Nothing to convert, regardless. */
- if (!stats.lonelf)
+ if (!will_convert_lf_to_crlf(len, &stats, crlf_action))
return 0;
- if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
- /* If we have any CR or CRLF line endings, we do not touch it */
- /* This is the new safer autocrlf-handling */
- if (stats.lonecr || stats.crlf )
- return 0;
-
- if (convert_is_binary(len, &stats))
- return 0;
- }
-
/* are we "faking" in place editing ? */
if (src == buf->buf)
to_free = strbuf_detach(buf, NULL);