@ -189,33 +189,25 @@ static enum eol output_eol(enum crlf_action crlf_action)
@@ -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)
@@ -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,
@@ -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,
@@ -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,
@@ -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);