diff options
author | Junio C Hamano <gitster@pobox.com> | 2016-12-01 21:34:42 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-12-01 21:34:42 +0300 |
commit | b365dafe2360c12353259432a2940c6123cd2b52 (patch) | |
tree | 3a44c43c393af77be58d0832fb07554ce08e9e8d /convert.c | |
parent | 55e9f0e5c9a918c246b7eae1fe2a2e954f6426af (diff) | |
parent | a0ad53c18100226cb1a138cb9b3bc3615170be8f (diff) |
Merge branch 'tb/t0027-raciness-fix' into jc/renormalize-merge-kill-safer-crlf
* tb/t0027-raciness-fix:
convert: Correct NNO tests and missing `LF will be replaced by CRLF`
Diffstat (limited to 'convert.c')
-rw-r--r-- | convert.c | 97 |
1 files changed, 57 insertions, 40 deletions
@@ -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); |