40e58429976a0145f4efcbcc24521e691df76753
1#!/bin/sh
2
3test_description='core.whitespace rules and git apply'
4
5. ./test-lib.sh
6
7prepare_test_file () {
8
9 # A line that has character X is touched iff RULE is in effect:
10 # X RULE
11 # ! trailing-space
12 # @ space-before-tab
13 # # indent-with-non-tab
14 # % tab-in-indent
15 sed -e "s/_/ /g" -e "s/>/ /" <<-\EOF
16 An_SP in an ordinary line>and a HT.
17 >A HT (%).
18 _>A SP and a HT (@%).
19 _>_A SP, a HT and a SP (@%).
20 _______Seven SP.
21 ________Eight SP (#).
22 _______>Seven SP and a HT (@%).
23 ________>Eight SP and a HT (@#%).
24 _______>_Seven SP, a HT and a SP (@%).
25 ________>_Eight SP, a HT and a SP (@#%).
26 _______________Fifteen SP (#).
27 _______________>Fifteen SP and a HT (@#%).
28 ________________Sixteen SP (#).
29 ________________>Sixteen SP and a HT (@#%).
30 _____a__Five SP, a non WS, two SP.
31 A line with a (!) trailing SP_
32 A line with a (!) trailing HT>
33 EOF
34}
35
36apply_patch () {
37 >target &&
38 sed -e "s|\([ab]\)/file|\1/target|" <patch |
39 git apply "$@"
40}
41
42test_fix () {
43 # fix should not barf
44 apply_patch --whitespace=fix || return 1
45
46 # find touched lines
47 $DIFF file target | sed -n -e "s/^> //p" >fixed
48
49 # the changed lines are all expeced to change
50 fixed_cnt=$(wc -l <fixed)
51 case "$1" in
52 '') expect_cnt=$fixed_cnt ;;
53 ?*) expect_cnt=$(grep "[$1]" <fixed | wc -l) ;;
54 esac
55 test $fixed_cnt -eq $expect_cnt || return 1
56
57 # and we are not missing anything
58 case "$1" in
59 '') expect_cnt=0 ;;
60 ?*) expect_cnt=$(grep "[$1]" <file | wc -l) ;;
61 esac
62 test $fixed_cnt -eq $expect_cnt || return 1
63
64 # Get the patch actually applied
65 git diff-files -p target >fixed-patch
66 test -s fixed-patch && return 0
67
68 # Make sure it is complaint-free
69 >target
70 git apply --whitespace=error-all <fixed-patch
71
72}
73
74test_expect_success setup '
75
76 >file &&
77 git add file &&
78 prepare_test_file >file &&
79 git diff-files -p >patch &&
80 >target &&
81 git add target
82
83'
84
85test_expect_success 'whitespace=nowarn, default rule' '
86
87 apply_patch --whitespace=nowarn &&
88 test_cmp file target
89
90'
91
92test_expect_success 'whitespace=warn, default rule' '
93
94 apply_patch --whitespace=warn &&
95 test_cmp file target
96
97'
98
99test_expect_success 'whitespace=error-all, default rule' '
100
101 apply_patch --whitespace=error-all && return 1
102 test -s target && return 1
103 : happy
104
105'
106
107test_expect_success 'whitespace=error-all, no rule' '
108
109 git config core.whitespace -trailing,-space-before,-indent &&
110 apply_patch --whitespace=error-all &&
111 test_cmp file target
112
113'
114
115test_expect_success 'whitespace=error-all, no rule (attribute)' '
116
117 git config --unset core.whitespace &&
118 echo "target -whitespace" >.gitattributes &&
119 apply_patch --whitespace=error-all &&
120 test_cmp file target
121
122'
123
124test_expect_success 'spaces inserted by tab-in-indent' '
125
126 git config core.whitespace -trailing,-space,-indent,tab &&
127 rm -f .gitattributes &&
128 test_fix % &&
129 sed -e "s/_/ /g" -e "s/>/ /" <<-\EOF >expect &&
130 An_SP in an ordinary line>and a HT.
131 ________A HT (%).
132 ________A SP and a HT (@%).
133 _________A SP, a HT and a SP (@%).
134 _______Seven SP.
135 ________Eight SP (#).
136 ________Seven SP and a HT (@%).
137 ________________Eight SP and a HT (@#%).
138 _________Seven SP, a HT and a SP (@%).
139 _________________Eight SP, a HT and a SP (@#%).
140 _______________Fifteen SP (#).
141 ________________Fifteen SP and a HT (@#%).
142 ________________Sixteen SP (#).
143 ________________________Sixteen SP and a HT (@#%).
144 _____a__Five SP, a non WS, two SP.
145 A line with a (!) trailing SP_
146 A line with a (!) trailing HT>
147 EOF
148 test_cmp expect target
149
150'
151
152for t in - ''
153do
154 case "$t" in '') tt='!' ;; *) tt= ;; esac
155 for s in - ''
156 do
157 case "$s" in '') ts='@' ;; *) ts= ;; esac
158 for i in - ''
159 do
160 case "$i" in '') ti='#' ;; *) ti= ;; esac
161 for h in - ''
162 do
163 [ -z "$h$i" ] && continue
164 case "$h" in '') th='%' ;; *) th= ;; esac
165 rule=${t}trailing,${s}space,${i}indent,${h}tab
166
167 rm -f .gitattributes
168 test_expect_success "rule=$rule" '
169 git config core.whitespace "$rule" &&
170 test_fix "$tt$ts$ti$th"
171 '
172
173 test_expect_success "rule=$rule (attributes)" '
174 git config --unset core.whitespace &&
175 echo "target whitespace=$rule" >.gitattributes &&
176 test_fix "$tt$ts$ti$th"
177 '
178
179 done
180 done
181 done
182done
183
184create_patch () {
185 sed -e "s/_/ /" <<-\EOF
186 diff --git a/target b/target
187 index e69de29..8bd6648 100644
188 --- a/target
189 +++ b/target
190 @@ -0,0 +1,3 @@
191 +An empty line follows
192 +
193 +A line with trailing whitespace and no newline_
194 \ No newline at end of file
195 EOF
196}
197
198test_expect_success 'trailing whitespace & no newline at the end of file' '
199 >target &&
200 create_patch >patch-file &&
201 git apply --whitespace=fix patch-file &&
202 grep "newline$" target &&
203 grep "^$" target
204'
205
206test_expect_success 'blank at EOF with --whitespace=fix (1)' '
207 test_might_fail git config --unset core.whitespace &&
208 rm -f .gitattributes &&
209
210 { echo a; echo b; echo c; } >one &&
211 git add one &&
212 { echo a; echo b; echo c; } >expect &&
213 { cat expect; echo; } >one &&
214 git diff -- one >patch &&
215
216 git checkout one &&
217 git apply --whitespace=fix patch &&
218 test_cmp expect one
219'
220
221test_expect_success 'blank at EOF with --whitespace=fix (2)' '
222 { echo a; echo b; echo c; } >one &&
223 git add one &&
224 { echo a; echo c; } >expect &&
225 { cat expect; echo; echo; } >one &&
226 git diff -- one >patch &&
227
228 git checkout one &&
229 git apply --whitespace=fix patch &&
230 test_cmp expect one
231'
232
233test_expect_success 'blank at EOF with --whitespace=fix (3)' '
234 { echo a; echo b; echo; } >one &&
235 git add one &&
236 { echo a; echo c; echo; } >expect &&
237 { cat expect; echo; echo; } >one &&
238 git diff -- one >patch &&
239
240 git checkout one &&
241 git apply --whitespace=fix patch &&
242 test_cmp expect one
243'
244
245test_expect_success 'blank at end of hunk, not at EOF with --whitespace=fix' '
246 { echo a; echo b; echo; echo; echo; echo; echo; echo d; } >one &&
247 git add one &&
248 { echo a; echo c; echo; echo; echo; echo; echo; echo; echo d; } >expect &&
249 cp expect one &&
250 git diff -- one >patch &&
251
252 git checkout one &&
253 git apply --whitespace=fix patch &&
254 test_cmp expect one
255'
256
257test_expect_success 'blank at EOF with --whitespace=warn' '
258 { echo a; echo b; echo c; } >one &&
259 git add one &&
260 echo >>one &&
261 cat one >expect &&
262 git diff -- one >patch &&
263
264 git checkout one &&
265 git apply --whitespace=warn patch 2>error &&
266 test_cmp expect one &&
267 grep "new blank line at EOF" error
268'
269
270test_expect_success 'blank at EOF with --whitespace=error' '
271 { echo a; echo b; echo c; } >one &&
272 git add one &&
273 cat one >expect &&
274 echo >>one &&
275 git diff -- one >patch &&
276
277 git checkout one &&
278 test_must_fail git apply --whitespace=error patch 2>error &&
279 test_cmp expect one &&
280 grep "new blank line at EOF" error
281'
282
283test_expect_success 'blank but not empty at EOF' '
284 { echo a; echo b; echo c; } >one &&
285 git add one &&
286 echo " " >>one &&
287 cat one >expect &&
288 git diff -- one >patch &&
289
290 git checkout one &&
291 git apply --whitespace=warn patch 2>error &&
292 test_cmp expect one &&
293 grep "new blank line at EOF" error
294'
295
296test_expect_success 'applying beyond EOF requires one non-blank context line' '
297 { echo; echo; echo; echo; } >one &&
298 git add one &&
299 { echo b; } >>one &&
300 git diff -- one >patch &&
301
302 git checkout one &&
303 { echo a; echo; } >one &&
304 cp one expect &&
305 test_must_fail git apply --whitespace=fix patch &&
306 test_cmp one expect &&
307 test_must_fail git apply --ignore-space-change --whitespace=fix patch &&
308 test_cmp one expect
309'
310
311test_expect_success 'tons of blanks at EOF should not apply' '
312 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
313 echo; echo; echo; echo;
314 done >one &&
315 git add one &&
316 echo a >>one &&
317 git diff -- one >patch &&
318
319 >one &&
320 test_must_fail git apply --whitespace=fix patch &&
321 test_must_fail git apply --ignore-space-change --whitespace=fix patch
322'
323
324test_expect_success 'missing blank line at end with --whitespace=fix' '
325 echo a >one &&
326 echo >>one &&
327 git add one &&
328 echo b >>one &&
329 cp one expect &&
330 git diff -- one >patch &&
331 echo a >one &&
332 cp one saved-one &&
333 test_must_fail git apply patch &&
334 git apply --whitespace=fix patch &&
335 test_cmp one expect &&
336 mv saved-one one &&
337 git apply --ignore-space-change --whitespace=fix patch &&
338 test_cmp one expect
339'
340
341test_expect_success 'two missing blank lines at end with --whitespace=fix' '
342 { echo a; echo; echo b; echo c; } >one &&
343 cp one no-blank-lines &&
344 { echo; echo; } >>one &&
345 git add one &&
346 echo d >>one &&
347 cp one expect &&
348 echo >>one &&
349 git diff -- one >patch &&
350 cp no-blank-lines one &&
351 test_must_fail git apply patch &&
352 git apply --whitespace=fix patch &&
353 test_cmp one expect &&
354 mv no-blank-lines one &&
355 test_must_fail git apply patch &&
356 git apply --ignore-space-change --whitespace=fix patch &&
357 test_cmp one expect
358'
359
360test_expect_success 'missing blank line at end, insert before end, --whitespace=fix' '
361 { echo a; echo; } >one &&
362 git add one &&
363 { echo b; echo a; echo; } >one &&
364 cp one expect &&
365 git diff -- one >patch &&
366 echo a >one &&
367 test_must_fail git apply patch &&
368 git apply --whitespace=fix patch &&
369 test_cmp one expect
370'
371
372test_expect_success 'shrink file with tons of missing blanks at end of file' '
373 { echo a; echo b; echo c; } >one &&
374 cp one no-blank-lines &&
375 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
376 echo; echo; echo; echo;
377 done >>one &&
378 git add one &&
379 echo a >one &&
380 cp one expect &&
381 git diff -- one >patch &&
382 cp no-blank-lines one &&
383 test_must_fail git apply patch &&
384 git apply --whitespace=fix patch &&
385 test_cmp one expect &&
386 mv no-blank-lines one &&
387 git apply --ignore-space-change --whitespace=fix patch &&
388 test_cmp one expect
389'
390
391test_expect_success 'missing blanks at EOF must only match blank lines' '
392 { echo a; echo b; } >one &&
393 git add one &&
394 { echo c; echo d; } >>one &&
395 git diff -- one >patch &&
396
397 echo a >one &&
398 test_must_fail git apply patch &&
399 test_must_fail git apply --whitespace=fix patch &&
400 test_must_fail git apply --ignore-space-change --whitespace=fix patch
401'
402
403sed -e's/Z//' >one <<EOF
404a
405b
406c
407 Z
408EOF
409
410test_expect_success 'missing blank line should match context line with spaces' '
411 git add one &&
412 echo d >>one &&
413 git diff -- one >patch &&
414 { echo a; echo b; echo c; } >one &&
415 cp one expect &&
416 { echo; echo d; } >>expect &&
417 git add one &&
418
419 git apply --whitespace=fix patch &&
420 test_cmp one expect
421'
422
423sed -e's/Z//' >one <<EOF
424a
425b
426c
427 Z
428EOF
429
430test_expect_success 'same, but with the --ignore-space-option' '
431 git add one &&
432 echo d >>one &&
433 cp one expect &&
434 git diff -- one >patch &&
435 { echo a; echo b; echo c; } >one &&
436 git add one &&
437
438 git checkout-index -f one &&
439 git apply --ignore-space-change --whitespace=fix patch &&
440 test_cmp one expect
441'
442
443test_expect_success 'same, but with CR-LF line endings && cr-at-eol set' '
444 git config core.whitespace cr-at-eol &&
445 printf "a\r\n" >one &&
446 printf "b\r\n" >>one &&
447 printf "c\r\n" >>one &&
448 cp one save-one &&
449 printf " \r\n" >>one &&
450 git add one &&
451 printf "d\r\n" >>one &&
452 cp one expect &&
453 git diff -- one >patch &&
454 mv save-one one &&
455
456 git apply --ignore-space-change --whitespace=fix patch &&
457 test_cmp one expect
458'
459
460test_expect_success 'same, but with CR-LF line endings && cr-at-eol unset' '
461 git config --unset core.whitespace &&
462 printf "a\r\n" >one &&
463 printf "b\r\n" >>one &&
464 printf "c\r\n" >>one &&
465 cp one save-one &&
466 printf " \r\n" >>one &&
467 git add one &&
468 cp one expect &&
469 printf "d\r\n" >>one &&
470 git diff -- one >patch &&
471 mv save-one one &&
472 echo d >>expect &&
473
474 git apply --ignore-space-change --whitespace=fix patch &&
475 test_cmp one expect
476'
477
478test_done