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