Skip to content

Commit 643b622

Browse files
committed
Merge branch 'tb/t0027-raciness-fix'
The t0027 test for CRLF conversion was timing dependent and flaky. * tb/t0027-raciness-fix: convert: Correct NNO tests and missing `LF will be replaced by CRLF`
2 parents aeb1b7f + a0ad53c commit 643b622

File tree

2 files changed

+60
-43
lines changed

2 files changed

+60
-43
lines changed

convert.c

Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -189,33 +189,25 @@ static enum eol output_eol(enum crlf_action crlf_action)
189189
}
190190

191191
static void check_safe_crlf(const char *path, enum crlf_action crlf_action,
192-
struct text_stat *stats, enum safe_crlf checksafe)
192+
struct text_stat *old_stats, struct text_stat *new_stats,
193+
enum safe_crlf checksafe)
193194
{
194-
if (!checksafe)
195-
return;
196-
197-
if (output_eol(crlf_action) == EOL_LF) {
195+
if (old_stats->crlf && !new_stats->crlf ) {
198196
/*
199-
* CRLFs would not be restored by checkout:
200-
* check if we'd remove CRLFs
197+
* CRLFs would not be restored by checkout
201198
*/
202-
if (stats->crlf) {
203-
if (checksafe == SAFE_CRLF_WARN)
204-
warning("CRLF will be replaced by LF in %s.\nThe file will have its original line endings in your working directory.", path);
205-
else /* i.e. SAFE_CRLF_FAIL */
206-
die("CRLF would be replaced by LF in %s.", path);
207-
}
208-
} else if (output_eol(crlf_action) == EOL_CRLF) {
199+
if (checksafe == SAFE_CRLF_WARN)
200+
warning("CRLF will be replaced by LF in %s.\nThe file will have its original line endings in your working directory.", path);
201+
else /* i.e. SAFE_CRLF_FAIL */
202+
die("CRLF would be replaced by LF in %s.", path);
203+
} else if (old_stats->lonelf && !new_stats->lonelf ) {
209204
/*
210-
* CRLFs would be added by checkout:
211-
* check if we have "naked" LFs
205+
* CRLFs would be added by checkout
212206
*/
213-
if (stats->lonelf) {
214-
if (checksafe == SAFE_CRLF_WARN)
215-
warning("LF will be replaced by CRLF in %s.\nThe file will have its original line endings in your working directory.", path);
216-
else /* i.e. SAFE_CRLF_FAIL */
217-
die("LF would be replaced by CRLF in %s", path);
218-
}
207+
if (checksafe == SAFE_CRLF_WARN)
208+
warning("LF will be replaced by CRLF in %s.\nThe file will have its original line endings in your working directory.", path);
209+
else /* i.e. SAFE_CRLF_FAIL */
210+
die("LF would be replaced by CRLF in %s", path);
219211
}
220212
}
221213

@@ -233,12 +225,35 @@ static int has_cr_in_index(const char *path)
233225
return has_cr;
234226
}
235227

228+
static int will_convert_lf_to_crlf(size_t len, struct text_stat *stats,
229+
enum crlf_action crlf_action)
230+
{
231+
if (output_eol(crlf_action) != EOL_CRLF)
232+
return 0;
233+
/* No "naked" LF? Nothing to convert, regardless. */
234+
if (!stats->lonelf)
235+
return 0;
236+
237+
if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
238+
/* If we have any CR or CRLF line endings, we do not touch it */
239+
/* This is the new safer autocrlf-handling */
240+
if (stats->lonecr || stats->crlf)
241+
return 0;
242+
243+
if (convert_is_binary(len, stats))
244+
return 0;
245+
}
246+
return 1;
247+
248+
}
249+
236250
static int crlf_to_git(const char *path, const char *src, size_t len,
237251
struct strbuf *buf,
238252
enum crlf_action crlf_action, enum safe_crlf checksafe)
239253
{
240254
struct text_stat stats;
241255
char *dst;
256+
int convert_crlf_into_lf;
242257

243258
if (crlf_action == CRLF_BINARY ||
244259
(src && !len))
@@ -252,6 +267,8 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
252267
return 1;
253268

254269
gather_stats(src, len, &stats);
270+
/* Optimization: No CRLF? Nothing to convert, regardless. */
271+
convert_crlf_into_lf = !!stats.crlf;
255272

256273
if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
257274
if (convert_is_binary(len, &stats))
@@ -263,12 +280,24 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
263280
if (checksafe == SAFE_CRLF_RENORMALIZE)
264281
checksafe = SAFE_CRLF_FALSE;
265282
else if (has_cr_in_index(path))
266-
return 0;
283+
convert_crlf_into_lf = 0;
267284
}
268-
check_safe_crlf(path, crlf_action, &stats, checksafe);
269-
270-
/* Optimization: No CRLF? Nothing to convert, regardless. */
271-
if (!stats.crlf)
285+
if (checksafe && len) {
286+
struct text_stat new_stats;
287+
memcpy(&new_stats, &stats, sizeof(new_stats));
288+
/* simulate "git add" */
289+
if (convert_crlf_into_lf) {
290+
new_stats.lonelf += new_stats.crlf;
291+
new_stats.crlf = 0;
292+
}
293+
/* simulate "git checkout" */
294+
if (will_convert_lf_to_crlf(len, &new_stats, crlf_action)) {
295+
new_stats.crlf += new_stats.lonelf;
296+
new_stats.lonelf = 0;
297+
}
298+
check_safe_crlf(path, crlf_action, &stats, &new_stats, checksafe);
299+
}
300+
if (!convert_crlf_into_lf)
272301
return 0;
273302

274303
/*
@@ -314,21 +343,9 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len,
314343
return 0;
315344

316345
gather_stats(src, len, &stats);
317-
318-
/* No "naked" LF? Nothing to convert, regardless. */
319-
if (!stats.lonelf)
346+
if (!will_convert_lf_to_crlf(len, &stats, crlf_action))
320347
return 0;
321348

322-
if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF) {
323-
/* If we have any CR or CRLF line endings, we do not touch it */
324-
/* This is the new safer autocrlf-handling */
325-
if (stats.lonecr || stats.crlf )
326-
return 0;
327-
328-
if (convert_is_binary(len, &stats))
329-
return 0;
330-
}
331-
332349
/* are we "faking" in place editing ? */
333350
if (src == buf->buf)
334351
to_free = strbuf_detach(buf, NULL);

t/t0027-auto-crlf.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,7 @@ commit_chk_wrnNNO () {
119119
fname=${pfx}_$f.txt &&
120120
cp $f $fname &&
121121
printf Z >>"$fname" &&
122-
git -c core.autocrlf=$crlf add $fname 2>/dev/null &&
123-
git -c core.autocrlf=$crlf commit -m "commit_$fname" $fname >"${pfx}_$f.err" 2>&1
122+
git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
124123
done
125124

126125
test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" '
@@ -417,7 +416,8 @@ commit_chk_wrnNNO "text" "" false "$WILC" "$WICL" "$WAMIX" "$WILC
417416
commit_chk_wrnNNO "text" "" true LF_CRLF "" LF_CRLF LF_CRLF ""
418417
commit_chk_wrnNNO "text" "" input "" CRLF_LF CRLF_LF "" CRLF_LF
419418

420-
test_expect_success 'create files cleanup' '
419+
test_expect_success 'commit NNO and cleanup' '
420+
git commit -m "commit files on top of NNO" &&
421421
rm -f *.txt &&
422422
git -c core.autocrlf=false reset --hard
423423
'

0 commit comments

Comments
 (0)