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 echo happy.
41'
42
43test_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
52test_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
61test_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
70test_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
79test_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
92test_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
99test_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
105test_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
118test_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
131test_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
145test_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
159test_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
169test_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
179test_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
190test_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
200test_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
210test_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
221test_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
253test_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
268test_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
278test_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
291test_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
301test_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
312test_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
323test_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
341test_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
354test_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
363test_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
375test_expect_success 'report no change after setting autocrlf' '
376 git config core.autocrlf true &&
377 touch * &&
378 git diff --exit-code
379'
380
381test_expect_success 'files are clean after checkout' '
382 rm * &&
383 git checkout -f &&
384 git diff --exit-code
385'
386
387cr_to_Q_no_NL () {
388 tr '\015' Q | tr -d '\012'
389}
390
391test_expect_success 'LF only file gets CRLF with autocrlf' '
392 test "$(cr_to_Q_no_NL < alllf)" = "IQamQallQLFQ"
393'
394
395test_expect_success 'Mixed file is still mixed with autocrlf' '
396 test "$(cr_to_Q_no_NL < mixed)" = "OhhereisCRLFQintext"
397'
398
399test_expect_success 'CRLF only file has CRLF with autocrlf' '
400 test "$(cr_to_Q_no_NL < allcrlf)" = "IQamQallQCRLFQ"
401'
402
403test_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
413test_done