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