}
}
+static int has_cr_in_index(const char *path)
+{
+ int pos, len;
+ unsigned long sz;
+ enum object_type type;
+ void *data;
+ int has_cr;
+ struct index_state *istate = &the_index;
+
+ len = strlen(path);
+ pos = index_name_pos(istate, path, len);
+ if (pos < 0) {
+ /*
+ * We might be in the middle of a merge, in which
+ * case we would read stage #2 (ours).
+ */
+ int i;
+ for (i = -pos - 1;
+ (pos < 0 && i < istate->cache_nr &&
+ !strcmp(istate->cache[i]->name, path));
+ i++)
+ if (ce_stage(istate->cache[i]) == 2)
+ pos = i;
+ }
+ if (pos < 0)
+ return 0;
+ data = read_sha1_file(istate->cache[pos]->sha1, &type, &sz);
+ if (!data || type != OBJ_BLOB) {
+ free(data);
+ return 0;
+ }
+
+ has_cr = memchr(data, '\r', sz) != NULL;
+ free(data);
+ return has_cr;
+}
+
static int crlf_to_git(const char *path, const char *src, size_t len,
struct strbuf *buf, int action, enum safe_crlf checksafe)
{
*/
if (is_binary(len, &stats))
return 0;
+
+ /*
+ * If the file in the index has any CR in it, do not convert.
+ * This is the new safer autocrlf handling.
+ */
+ if (has_cr_in_index(path))
+ return 0;
}
check_safe_crlf(path, action, &stats, checksafe);
return 0;
if (action == CRLF_GUESS) {
+ /* 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)
+ return 0;
+
/* If we have any bare CR characters, we're not going to touch it */
if (stats.cr != stats.crlf)
return 0;
git diff
'
+# Some more tests here to add new autocrlf functionality.
+# We want to have a known state here, so start a bit from scratch
+
+test_expect_success 'setting up for new autocrlf tests' '
+ git config core.autocrlf false &&
+ git config core.safecrlf false &&
+ rm -rf .????* * &&
+ for w in I am all LF; do echo $w; done >alllf &&
+ for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
+ for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
+ git add -A . &&
+ git commit -m "alllf, allcrlf and mixed only" &&
+ git tag -a -m "message" autocrlf-checkpoint
+'
+
+test_expect_success 'report no change after setting autocrlf' '
+ git config core.autocrlf true &&
+ touch * &&
+ git diff --exit-code
+'
+
+test_expect_success 'files are clean after checkout' '
+ rm * &&
+ git checkout -f &&
+ git diff --exit-code
+'
+
+cr_to_Q_no_NL () {
+ tr '\015' Q | tr -d '\012'
+}
+
+test_expect_success 'LF only file gets CRLF with autocrlf' '
+ test "$(cr_to_Q_no_NL < alllf)" = "IQamQallQLFQ"
+'
+
+test_expect_success 'Mixed file is still mixed with autocrlf' '
+ test "$(cr_to_Q_no_NL < mixed)" = "OhhereisCRLFQintext"
+'
+
+test_expect_success 'CRLF only file has CRLF with autocrlf' '
+ test "$(cr_to_Q_no_NL < allcrlf)" = "IQamQallQCRLFQ"
+'
+
+test_expect_success 'New CRLF file gets LF in repo' '
+ tr -d "\015" < alllf | append_cr > alllf2 &&
+ git add alllf2 &&
+ git commit -m "alllf2 added" &&
+ git config core.autocrlf false &&
+ rm * &&
+ git checkout -f &&
+ test_cmp alllf alllf2
+'
test_done