1#!/bin/sh
2
3test_description='CRLF conversion'
4
5. ./test-lib.sh
6
7q_to_nul () {
8 perl -pe 'y/Q/\000/'
9}
10
11q_to_cr () {
12 tr Q '\015'
13}
14
15append_cr () {
16 sed -e 's/$/Q/' | tr Q '\015'
17}
18
19remove_cr () {
20 tr '\015' Q <"$1" | grep Q >/dev/null &&
21 tr '\015' Q <"$1" | sed -ne 's/Q$//p'
22}
23
24test_expect_success setup '
25
26 git config core.autocrlf false &&
27
28 for w in Hello world how are you; do echo $w; done >one &&
29 mkdir dir &&
30 for w in I am very very fine thank you; do echo $w; done >dir/two &&
31 for w in Oh here is NULQin text here; do echo $w; done | q_to_nul >three &&
32 git add . &&
33
34 git commit -m initial &&
35
36 one=`git rev-parse HEAD:one` &&
37 dir=`git rev-parse HEAD:dir` &&
38 two=`git rev-parse HEAD:dir/two` &&
39 three=`git rev-parse HEAD:three` &&
40
41 for w in Some extra lines here; do echo $w; done >>one &&
42 git diff >patch.file &&
43 patched=`git hash-object --stdin <one` &&
44 git read-tree --reset -u HEAD &&
45
46 echo happy.
47'
48
49test_expect_success 'safecrlf: autocrlf=input, all CRLF' '
50
51 git config core.autocrlf input &&
52 git config core.safecrlf true &&
53
54 for w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&
55 test_must_fail git add allcrlf
56'
57
58test_expect_success 'safecrlf: autocrlf=input, mixed LF/CRLF' '
59
60 git config core.autocrlf input &&
61 git config core.safecrlf true &&
62
63 for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
64 test_must_fail git add mixed
65'
66
67test_expect_success 'safecrlf: autocrlf=true, all LF' '
68
69 git config core.autocrlf true &&
70 git config core.safecrlf true &&
71
72 for w in I am all LF; do echo $w; done >alllf &&
73 test_must_fail git add alllf
74'
75
76test_expect_success 'safecrlf: autocrlf=true mixed LF/CRLF' '
77
78 git config core.autocrlf true &&
79 git config core.safecrlf true &&
80
81 for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&
82 test_must_fail git add mixed
83'
84
85test_expect_success 'safecrlf: print warning only once' '
86
87 git config core.autocrlf input &&
88 git config core.safecrlf warn &&
89
90 for w in I am all LF; do echo $w; done >doublewarn &&
91 git add doublewarn &&
92 git commit -m "nowarn" &&
93 for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >doublewarn &&
94 test $(git add doublewarn 2>&1 | grep "CRLF will be replaced by LF" | wc -l) = 1
95'
96
97test_expect_success 'switch off autocrlf, safecrlf, reset HEAD' '
98 git config core.autocrlf false &&
99 git config core.safecrlf false &&
100 git reset --hard HEAD^
101'
102
103test_expect_success 'update with autocrlf=input' '
104
105 rm -f tmp one dir/two three &&
106 git read-tree --reset -u HEAD &&
107 git config core.autocrlf input &&
108
109 for f in one dir/two
110 do
111 append_cr <$f >tmp && mv -f tmp $f &&
112 git update-index -- $f || {
113 echo Oops
114 false
115 break
116 }
117 done &&
118
119 differs=`git diff-index --cached HEAD` &&
120 test -z "$differs" || {
121 echo Oops "$differs"
122 false
123 }
124
125'
126
127test_expect_success 'update with autocrlf=true' '
128
129 rm -f tmp one dir/two three &&
130 git read-tree --reset -u HEAD &&
131 git config core.autocrlf true &&
132
133 for f in one dir/two
134 do
135 append_cr <$f >tmp && mv -f tmp $f &&
136 git update-index -- $f || {
137 echo "Oops $f"
138 false
139 break
140 }
141 done &&
142
143 differs=`git diff-index --cached HEAD` &&
144 test -z "$differs" || {
145 echo Oops "$differs"
146 false
147 }
148
149'
150
151test_expect_success 'checkout with autocrlf=true' '
152
153 rm -f tmp one dir/two three &&
154 git config core.autocrlf true &&
155 git read-tree --reset -u HEAD &&
156
157 for f in one dir/two
158 do
159 remove_cr "$f" >tmp && mv -f tmp $f &&
160 git update-index -- $f || {
161 echo "Eh? $f"
162 false
163 break
164 }
165 done &&
166 test "$one" = `git hash-object --stdin <one` &&
167 test "$two" = `git hash-object --stdin <dir/two` &&
168 differs=`git diff-index --cached HEAD` &&
169 test -z "$differs" || {
170 echo Oops "$differs"
171 false
172 }
173'
174
175test_expect_success 'checkout with autocrlf=input' '
176
177 rm -f tmp one dir/two three &&
178 git config core.autocrlf input &&
179 git read-tree --reset -u HEAD &&
180
181 for f in one dir/two
182 do
183 if remove_cr "$f" >/dev/null
184 then
185 echo "Eh? $f"
186 false
187 break
188 else
189 git update-index -- $f
190 fi
191 done &&
192 test "$one" = `git hash-object --stdin <one` &&
193 test "$two" = `git hash-object --stdin <dir/two` &&
194 differs=`git diff-index --cached HEAD` &&
195 test -z "$differs" || {
196 echo Oops "$differs"
197 false
198 }
199'
200
201test_expect_success 'apply patch (autocrlf=input)' '
202
203 rm -f tmp one dir/two three &&
204 git config core.autocrlf input &&
205 git read-tree --reset -u HEAD &&
206
207 git apply patch.file &&
208 test "$patched" = "`git hash-object --stdin <one`" || {
209 echo "Eh? apply without index"
210 false
211 }
212'
213
214test_expect_success 'apply patch --cached (autocrlf=input)' '
215
216 rm -f tmp one dir/two three &&
217 git config core.autocrlf input &&
218 git read-tree --reset -u HEAD &&
219
220 git apply --cached patch.file &&
221 test "$patched" = `git rev-parse :one` || {
222 echo "Eh? apply with --cached"
223 false
224 }
225'
226
227test_expect_success 'apply patch --index (autocrlf=input)' '
228
229 rm -f tmp one dir/two three &&
230 git config core.autocrlf input &&
231 git read-tree --reset -u HEAD &&
232
233 git apply --index patch.file &&
234 test "$patched" = `git rev-parse :one` &&
235 test "$patched" = `git hash-object --stdin <one` || {
236 echo "Eh? apply with --index"
237 false
238 }
239'
240
241test_expect_success 'apply patch (autocrlf=true)' '
242
243 rm -f tmp one dir/two three &&
244 git config core.autocrlf true &&
245 git read-tree --reset -u HEAD &&
246
247 git apply patch.file &&
248 test "$patched" = "`remove_cr one | git hash-object --stdin`" || {
249 echo "Eh? apply without index"
250 false
251 }
252'
253
254test_expect_success 'apply patch --cached (autocrlf=true)' '
255
256 rm -f tmp one dir/two three &&
257 git config core.autocrlf true &&
258 git read-tree --reset -u HEAD &&
259
260 git apply --cached patch.file &&
261 test "$patched" = `git rev-parse :one` || {
262 echo "Eh? apply without index"
263 false
264 }
265'
266
267test_expect_success 'apply patch --index (autocrlf=true)' '
268
269 rm -f tmp one dir/two three &&
270 git config core.autocrlf true &&
271 git read-tree --reset -u HEAD &&
272
273 git apply --index patch.file &&
274 test "$patched" = `git rev-parse :one` &&
275 test "$patched" = "`remove_cr one | git hash-object --stdin`" || {
276 echo "Eh? apply with --index"
277 false
278 }
279'
280
281test_expect_success '.gitattributes says two is binary' '
282
283 rm -f tmp one dir/two three &&
284 echo "two -crlf" >.gitattributes &&
285 git config core.autocrlf true &&
286 git read-tree --reset -u HEAD &&
287
288 if remove_cr dir/two >/dev/null
289 then
290 echo "Huh?"
291 false
292 else
293 : happy
294 fi &&
295
296 if remove_cr one >/dev/null
297 then
298 : happy
299 else
300 echo "Huh?"
301 false
302 fi &&
303
304 if remove_cr three >/dev/null
305 then
306 echo "Huh?"
307 false
308 else
309 : happy
310 fi
311'
312
313test_expect_success '.gitattributes says two is input' '
314
315 rm -f tmp one dir/two three &&
316 echo "two crlf=input" >.gitattributes &&
317 git read-tree --reset -u HEAD &&
318
319 if remove_cr dir/two >/dev/null
320 then
321 echo "Huh?"
322 false
323 else
324 : happy
325 fi
326'
327
328test_expect_success '.gitattributes says two and three are text' '
329
330 rm -f tmp one dir/two three &&
331 echo "t* crlf" >.gitattributes &&
332 git read-tree --reset -u HEAD &&
333
334 if remove_cr dir/two >/dev/null
335 then
336 : happy
337 else
338 echo "Huh?"
339 false
340 fi &&
341
342 if remove_cr three >/dev/null
343 then
344 : happy
345 else
346 echo "Huh?"
347 false
348 fi
349'
350
351test_expect_success 'in-tree .gitattributes (1)' '
352
353 echo "one -crlf" >>.gitattributes &&
354 git add .gitattributes &&
355 git commit -m "Add .gitattributes" &&
356
357 rm -rf tmp one dir .gitattributes patch.file three &&
358 git read-tree --reset -u HEAD &&
359
360 if remove_cr one >/dev/null
361 then
362 echo "Eh? one should not have CRLF"
363 false
364 else
365 : happy
366 fi &&
367 remove_cr three >/dev/null || {
368 echo "Eh? three should still have CRLF"
369 false
370 }
371'
372
373test_expect_success 'in-tree .gitattributes (2)' '
374
375 rm -rf tmp one dir .gitattributes patch.file three &&
376 git read-tree --reset HEAD &&
377 git checkout-index -f -q -u -a &&
378
379 if remove_cr one >/dev/null
380 then
381 echo "Eh? one should not have CRLF"
382 false
383 else
384 : happy
385 fi &&
386 remove_cr three >/dev/null || {
387 echo "Eh? three should still have CRLF"
388 false
389 }
390'
391
392test_expect_success 'in-tree .gitattributes (3)' '
393
394 rm -rf tmp one dir .gitattributes patch.file three &&
395 git read-tree --reset HEAD &&
396 git checkout-index -u .gitattributes &&
397 git checkout-index -u one dir/two three &&
398
399 if remove_cr one >/dev/null
400 then
401 echo "Eh? one should not have CRLF"
402 false
403 else
404 : happy
405 fi &&
406 remove_cr three >/dev/null || {
407 echo "Eh? three should still have CRLF"
408 false
409 }
410'
411
412test_expect_success 'in-tree .gitattributes (4)' '
413
414 rm -rf tmp one dir .gitattributes patch.file three &&
415 git read-tree --reset HEAD &&
416 git checkout-index -u one dir/two three &&
417 git checkout-index -u .gitattributes &&
418
419 if remove_cr one >/dev/null
420 then
421 echo "Eh? one should not have CRLF"
422 false
423 else
424 : happy
425 fi &&
426 remove_cr three >/dev/null || {
427 echo "Eh? three should still have CRLF"
428 false
429 }
430'
431
432test_expect_success 'checkout with existing .gitattributes' '
433
434 git config core.autocrlf true &&
435 git config --unset core.safecrlf &&
436 echo ".file2 -crlfQ" | q_to_cr >> .gitattributes &&
437 git add .gitattributes &&
438 git commit -m initial &&
439 echo ".file -crlfQ" | q_to_cr >> .gitattributes &&
440 echo "contents" > .file &&
441 git add .gitattributes .file &&
442 git commit -m second &&
443
444 git checkout master~1 &&
445 git checkout master &&
446 test "$(git diff-files --raw)" = ""
447
448'
449
450test_expect_success 'checkout when deleting .gitattributes' '
451
452 git rm .gitattributes &&
453 echo "contentsQ" | q_to_cr > .file2 &&
454 git add .file2 &&
455 git commit -m third
456
457 git checkout master~1 &&
458 git checkout master &&
459 remove_cr .file2 >/dev/null
460
461'
462
463test_expect_success 'invalid .gitattributes (must not crash)' '
464
465 echo "three +crlf" >>.gitattributes &&
466 git diff
467
468'
469
470test_done