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