@@ -189,33 +189,25 @@ static enum eol output_eol(enum crlf_action crlf_action)
189
189
}
190
190
191
191
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 )
193
194
{
194
- if (!checksafe )
195
- return ;
196
-
197
- if (output_eol (crlf_action ) == EOL_LF ) {
195
+ if (old_stats -> crlf && !new_stats -> crlf ) {
198
196
/*
199
- * CRLFs would not be restored by checkout:
200
- * check if we'd remove CRLFs
197
+ * CRLFs would not be restored by checkout
201
198
*/
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 ) {
209
204
/*
210
- * CRLFs would be added by checkout:
211
- * check if we have "naked" LFs
205
+ * CRLFs would be added by checkout
212
206
*/
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 );
219
211
}
220
212
}
221
213
@@ -233,12 +225,35 @@ static int has_cr_in_index(const char *path)
233
225
return has_cr ;
234
226
}
235
227
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
+
236
250
static int crlf_to_git (const char * path , const char * src , size_t len ,
237
251
struct strbuf * buf ,
238
252
enum crlf_action crlf_action , enum safe_crlf checksafe )
239
253
{
240
254
struct text_stat stats ;
241
255
char * dst ;
256
+ int convert_crlf_into_lf ;
242
257
243
258
if (crlf_action == CRLF_BINARY ||
244
259
(src && !len ))
@@ -252,6 +267,8 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
252
267
return 1 ;
253
268
254
269
gather_stats (src , len , & stats );
270
+ /* Optimization: No CRLF? Nothing to convert, regardless. */
271
+ convert_crlf_into_lf = !!stats .crlf ;
255
272
256
273
if (crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_INPUT || crlf_action == CRLF_AUTO_CRLF ) {
257
274
if (convert_is_binary (len , & stats ))
@@ -263,12 +280,24 @@ static int crlf_to_git(const char *path, const char *src, size_t len,
263
280
if (checksafe == SAFE_CRLF_RENORMALIZE )
264
281
checksafe = SAFE_CRLF_FALSE ;
265
282
else if (has_cr_in_index (path ))
266
- return 0 ;
283
+ convert_crlf_into_lf = 0 ;
267
284
}
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 )
272
301
return 0 ;
273
302
274
303
/*
@@ -314,21 +343,9 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len,
314
343
return 0 ;
315
344
316
345
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 ))
320
347
return 0 ;
321
348
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
-
332
349
/* are we "faking" in place editing ? */
333
350
if (src == buf -> buf )
334
351
to_free = strbuf_detach (buf , NULL );
0 commit comments