struct text_stat {
/* NUL, CR, LF and CRLF counts */
- unsigned nul, cr, lf, crlf;
+ unsigned nul, lonecr, lonelf, crlf;
/* These are just approximations! */
unsigned printable, nonprintable;
for (i = 0; i < size; i++) {
unsigned char c = buf[i];
if (c == '\r') {
- stats->cr++;
- if (i+1 < size && buf[i+1] == '\n')
+ if (i+1 < size && buf[i+1] == '\n') {
stats->crlf++;
+ i++;
+ } else
+ stats->lonecr++;
continue;
}
if (c == '\n') {
- stats->lf++;
+ stats->lonelf++;
continue;
}
if (c == 127)
*/
static int convert_is_binary(unsigned long size, const struct text_stat *stats)
{
- if (stats->cr != stats->crlf)
+ if (stats->lonecr)
return 1;
if (stats->nul)
return 1;
static unsigned int gather_convert_stats(const char *data, unsigned long size)
{
struct text_stat stats;
+ int ret = 0;
if (!data || !size)
return 0;
gather_stats(data, size, &stats);
if (convert_is_binary(size, &stats))
- return CONVERT_STAT_BITS_BIN;
- else if (stats.crlf && stats.crlf == stats.lf)
- return CONVERT_STAT_BITS_TXT_CRLF;
- else if (stats.crlf && stats.lf)
- return CONVERT_STAT_BITS_TXT_CRLF | CONVERT_STAT_BITS_TXT_LF;
- else if (stats.lf)
- return CONVERT_STAT_BITS_TXT_LF;
- else
- return 0;
+ ret |= CONVERT_STAT_BITS_BIN;
+ if (stats.crlf)
+ ret |= CONVERT_STAT_BITS_TXT_CRLF;
+ if (stats.lonelf)
+ ret |= CONVERT_STAT_BITS_TXT_LF;
+
+ return ret;
}
static const char *gather_convert_stats_ascii(const char *data, unsigned long size)
* CRLFs would be added by checkout:
* check if we have "naked" LFs
*/
- if (stats->lf != stats->crlf) {
+ 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 */
check_safe_crlf(path, crlf_action, &stats, checksafe);
- /* Optimization: No CR? Nothing to convert, regardless. */
- if (!stats.cr)
+ /* Optimization: No CRLF? Nothing to convert, regardless. */
+ if (!stats.crlf)
return 0;
/*
gather_stats(src, len, &stats);
- /* No LF? Nothing to convert, regardless. */
- if (!stats.lf)
- return 0;
-
- /* Was it already in CRLF format? */
- if (stats.lf == stats.crlf)
+ /* 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 (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.cr > 0 || stats.crlf > 0)
+ if (stats.lonecr || stats.crlf )
return 0;
}
if (src == buf->buf)
to_free = strbuf_detach(buf, NULL);
- strbuf_grow(buf, len + stats.lf - stats.crlf);
+ strbuf_grow(buf, len + stats.lonelf);
for (;;) {
const char *nl = memchr(src, '\n', len);
if (!nl)
struct async async;
struct filter_params params;
- if (!cmd)
+ if (!cmd || !*cmd)
return 0;
if (!dst)
const char *value = check->value;
if (ATTR_TRUE(value))
- return text_eol_is_crlf() ? CRLF_TEXT_CRLF : CRLF_TEXT_INPUT;
+ return CRLF_TEXT;
else if (ATTR_FALSE(value))
return CRLF_BINARY;
else if (ATTR_UNSET(value))
}
if (!git_check_attr(path, NUM_CONV_ATTRS, ccheck)) {
- enum eol eol_attr;
ca->crlf_action = git_path_check_crlf(ccheck + 4);
if (ca->crlf_action == CRLF_UNDEFINED)
ca->crlf_action = git_path_check_crlf(ccheck + 0);
ca->attr_action = ca->crlf_action;
ca->ident = git_path_check_ident(ccheck + 1);
ca->drv = git_path_check_convert(ccheck + 2);
- if (ca->crlf_action == CRLF_BINARY)
- return;
- eol_attr = git_path_check_eol(ccheck + 3);
- if (eol_attr == EOL_LF)
- ca->crlf_action = CRLF_TEXT_INPUT;
- else if (eol_attr == EOL_CRLF)
- ca->crlf_action = CRLF_TEXT_CRLF;
+ if (ca->crlf_action != CRLF_BINARY) {
+ enum eol eol_attr = git_path_check_eol(ccheck + 3);
+ if (eol_attr == EOL_LF)
+ ca->crlf_action = CRLF_TEXT_INPUT;
+ else if (eol_attr == EOL_CRLF)
+ ca->crlf_action = CRLF_TEXT_CRLF;
+ }
+ ca->attr_action = ca->crlf_action;
} else {
ca->drv = NULL;
ca->crlf_action = CRLF_UNDEFINED;
struct stream_filter *get_stream_filter(const char *path, const unsigned char *sha1)
{
struct conv_attrs ca;
- enum crlf_action crlf_action;
struct stream_filter *filter = NULL;
convert_attrs(&ca, path);
-
if (ca.drv && (ca.drv->smudge || ca.drv->clean))
- return filter;
+ return NULL;
+
+ if (ca.crlf_action == CRLF_AUTO || ca.crlf_action == CRLF_AUTO_CRLF)
+ return NULL;
if (ca.ident)
filter = ident_filter(sha1);
- crlf_action = ca.crlf_action;
-
- if ((crlf_action == CRLF_BINARY) ||
- crlf_action == CRLF_AUTO_INPUT ||
- (crlf_action == CRLF_TEXT_INPUT))
- filter = cascade_filter(filter, &null_filter_singleton);
-
- else if (output_eol(crlf_action) == EOL_CRLF &&
- !(crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_CRLF))
+ if (output_eol(ca.crlf_action) == EOL_CRLF)
filter = cascade_filter(filter, lf_to_crlf_filter());
+ else
+ filter = cascade_filter(filter, &null_filter_singleton);
return filter;
}