Merge branch 'fg/autocrlf'
* fg/autocrlf: autocrlf: Make it work also for un-normalized repositories
This commit is contained in:
commit
d249515f29
49
convert.c
49
convert.c
@ -120,6 +120,43 @@ static void check_safe_crlf(const char *path, int action,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
static int crlf_to_git(const char *path, const char *src, size_t len,
|
||||||
struct strbuf *buf, int action, enum safe_crlf checksafe)
|
struct strbuf *buf, int action, enum safe_crlf checksafe)
|
||||||
{
|
{
|
||||||
@ -145,6 +182,13 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
|
|||||||
*/
|
*/
|
||||||
if (is_binary(len, &stats))
|
if (is_binary(len, &stats))
|
||||||
return 0;
|
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);
|
check_safe_crlf(path, action, &stats, checksafe);
|
||||||
@ -203,6 +247,11 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (action == CRLF_GUESS) {
|
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 we have any bare CR characters, we're not going to touch it */
|
||||||
if (stats.cr != stats.crlf)
|
if (stats.cr != stats.crlf)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -453,5 +453,57 @@ test_expect_success 'invalid .gitattributes (must not crash)' '
|
|||||||
git diff
|
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
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user