Git 2.45
[git/gitster.git] / t / t4124-apply-ws-rule.sh
blob485c7d2d124ade54d00f8752399be91f43eefbc8
1 #!/bin/sh
3 test_description='core.whitespace rules and git apply'
5 . ./test-lib.sh
7 prepare_test_file () {
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 (default tab width 8)
14 # = indent-with-non-tab,tabwidth=16
15 # % tab-in-indent
16 sed -e "s/_/ /g" -e "s/>/ /" <<-\EOF
17 An_SP in an ordinary line>and a HT.
18 >A HT (%).
19 _>A SP and a HT (@%).
20 _>_A SP, a HT and a SP (@%).
21 _______Seven SP.
22 ________Eight SP (#).
23 _______>Seven SP and a HT (@%).
24 ________>Eight SP and a HT (@#%).
25 _______>_Seven SP, a HT and a SP (@%).
26 ________>_Eight SP, a HT and a SP (@#%).
27 _______________Fifteen SP (#).
28 _______________>Fifteen SP and a HT (@#%).
29 ________________Sixteen SP (#=).
30 ________________>Sixteen SP and a HT (@#%=).
31 _____a__Five SP, a non WS, two SP.
32 A line with a (!) trailing SP_
33 A line with a (!) trailing HT>
34 EOF
37 apply_patch () {
38 cmd_prefix= &&
39 if test "x$1" = 'x!'
40 then
41 cmd_prefix=test_must_fail &&
42 shift
43 fi &&
44 >target &&
45 sed -e "s|\([ab]\)/file|\1/target|" <patch |
46 $cmd_prefix git apply "$@"
49 test_fix () {
50 # fix should not barf
51 apply_patch --whitespace=fix || return 1
53 # find touched lines
54 $DIFF file target | sed -n -e "s/^> //p" >fixed
55 # busybox's diff(1) doesn't output normal format
56 if ! test -s fixed
57 then
58 $DIFF -u file target |
59 grep -v '^+++ target' |
60 sed -ne "/^+/s/+//p" >fixed
63 # the changed lines are all expected to change
64 fixed_cnt=$(wc -l <fixed)
65 case "$1" in
66 '') expect_cnt=$fixed_cnt ;;
67 ?*) expect_cnt=$(grep "[$1]" <fixed | wc -l) ;;
68 esac
69 test $fixed_cnt -eq $expect_cnt || return 1
71 # and we are not missing anything
72 case "$1" in
73 '') expect_cnt=0 ;;
74 ?*) expect_cnt=$(grep "[$1]" <file | wc -l) ;;
75 esac
76 test $fixed_cnt -eq $expect_cnt || return 1
78 # Get the patch actually applied
79 git diff-files -p target >fixed-patch
80 test -s fixed-patch && return 0
82 # Make sure it is complaint-free
83 >target
84 git apply --whitespace=error-all <fixed-patch
88 test_expect_success setup '
90 >file &&
91 git add file &&
92 prepare_test_file >file &&
93 git diff-files -p >patch &&
94 >target &&
95 git add target
99 test_expect_success 'whitespace=nowarn, default rule' '
101 apply_patch --whitespace=nowarn &&
102 test_cmp file target
106 test_expect_success 'whitespace=warn, default rule' '
108 apply_patch --whitespace=warn &&
109 test_cmp file target
113 test_expect_success 'whitespace=error-all, default rule' '
115 apply_patch ! --whitespace=error-all &&
116 test_must_be_empty target
120 test_expect_success 'whitespace=error-all, no rule' '
122 git config core.whitespace -trailing,-space-before,-indent &&
123 apply_patch --whitespace=error-all &&
124 test_cmp file target
128 test_expect_success 'whitespace=error-all, no rule (attribute)' '
130 git config --unset core.whitespace &&
131 echo "target -whitespace" >.gitattributes &&
132 apply_patch --whitespace=error-all &&
133 test_cmp file target
137 test_expect_success 'spaces inserted by tab-in-indent' '
139 git config core.whitespace -trailing,-space,-indent,tab &&
140 rm -f .gitattributes &&
141 test_fix % &&
142 sed -e "s/_/ /g" -e "s/>/ /" <<-\EOF >expect &&
143 An_SP in an ordinary line>and a HT.
144 ________A HT (%).
145 ________A SP and a HT (@%).
146 _________A SP, a HT and a SP (@%).
147 _______Seven SP.
148 ________Eight SP (#).
149 ________Seven SP and a HT (@%).
150 ________________Eight SP and a HT (@#%).
151 _________Seven SP, a HT and a SP (@%).
152 _________________Eight SP, a HT and a SP (@#%).
153 _______________Fifteen SP (#).
154 ________________Fifteen SP and a HT (@#%).
155 ________________Sixteen SP (#=).
156 ________________________Sixteen SP and a HT (@#%=).
157 _____a__Five SP, a non WS, two SP.
158 A line with a (!) trailing SP_
159 A line with a (!) trailing HT>
161 test_cmp expect target
165 for t in - ''
167 case "$t" in '') tt='!' ;; *) tt= ;; esac
168 for s in - ''
170 case "$s" in '') ts='@' ;; *) ts= ;; esac
171 for i in - ''
173 case "$i" in '') ti='#' ti16='=';; *) ti= ti16= ;; esac
174 for h in - ''
176 [ -z "$h$i" ] && continue
177 case "$h" in '') th='%' ;; *) th= ;; esac
178 rule=${t}trailing,${s}space,${i}indent,${h}tab
180 rm -f .gitattributes
181 test_expect_success "rule=$rule" '
182 git config core.whitespace "$rule" &&
183 test_fix "$tt$ts$ti$th"
186 test_expect_success "rule=$rule,tabwidth=16" '
187 git config core.whitespace "$rule,tabwidth=16" &&
188 test_fix "$tt$ts$ti16$th"
191 test_expect_success "rule=$rule (attributes)" '
192 git config --unset core.whitespace &&
193 echo "target whitespace=$rule" >.gitattributes &&
194 test_fix "$tt$ts$ti$th"
197 test_expect_success "rule=$rule,tabwidth=16 (attributes)" '
198 echo "target whitespace=$rule,tabwidth=16" >.gitattributes &&
199 test_fix "$tt$ts$ti16$th"
202 done
203 done
204 done
205 done
207 create_patch () {
208 sed -e "s/_/ /" <<-\EOF
209 diff --git a/target b/target
210 index e69de29..8bd6648 100644
211 --- a/target
212 +++ b/target
213 @@ -0,0 +1,3 @@
214 +An empty line follows
216 +A line with trailing whitespace and no newline_
217 \ No newline at end of file
221 test_expect_success 'trailing whitespace & no newline at the end of file' '
222 >target &&
223 create_patch >patch-file &&
224 git apply --whitespace=fix patch-file &&
225 grep "newline$" target &&
226 grep "^$" target
229 test_expect_success 'blank at EOF with --whitespace=fix (1)' '
230 test_might_fail git config --unset core.whitespace &&
231 rm -f .gitattributes &&
233 test_write_lines a b c >one &&
234 git add one &&
235 test_write_lines a b c >expect &&
236 { cat expect && echo; } >one &&
237 git diff -- one >patch &&
239 git checkout one &&
240 git apply --whitespace=fix patch &&
241 test_cmp expect one
244 test_expect_success 'blank at EOF with --whitespace=fix (2)' '
245 test_write_lines a b c >one &&
246 git add one &&
247 test_write_lines a b >expect &&
248 { cat expect && test_write_lines "" ""; } >one &&
249 git diff -- one >patch &&
251 git checkout one &&
252 git apply --whitespace=fix patch &&
253 test_cmp expect one
256 test_expect_success 'blank at EOF with --whitespace=fix (3)' '
257 test_write_lines a b "" >one &&
258 git add one &&
259 test_write_lines a c "" >expect &&
260 { cat expect && test_write_lines "" ""; } >one &&
261 git diff -- one >patch &&
263 git checkout one &&
264 git apply --whitespace=fix patch &&
265 test_cmp expect one
268 test_expect_success 'blank at end of hunk, not at EOF with --whitespace=fix' '
269 test_write_lines a b "" "" "" "" "" d >one &&
270 git add one &&
271 test_write_lines a b "" "" "" "" "" "" d >expect &&
272 cp expect one &&
273 git diff -- one >patch &&
275 git checkout one &&
276 git apply --whitespace=fix patch &&
277 test_cmp expect one
280 test_expect_success 'blank at EOF with --whitespace=warn' '
281 test_write_lines a b c >one &&
282 git add one &&
283 echo >>one &&
284 cat one >expect &&
285 git diff -- one >patch &&
287 git checkout one &&
288 git apply --whitespace=warn patch 2>error &&
289 test_cmp expect one &&
290 grep "new blank line at EOF" error
293 test_expect_success 'blank at EOF with --whitespace=error' '
294 test_write_lines a b c >one &&
295 git add one &&
296 cat one >expect &&
297 echo >>one &&
298 git diff -- one >patch &&
300 git checkout one &&
301 test_must_fail git apply --whitespace=error patch 2>error &&
302 test_cmp expect one &&
303 grep "new blank line at EOF" error
306 test_expect_success 'blank but not empty at EOF' '
307 test_write_lines a b c >one &&
308 git add one &&
309 echo " " >>one &&
310 cat one >expect &&
311 git diff -- one >patch &&
313 git checkout one &&
314 git apply --whitespace=warn patch 2>error &&
315 test_cmp expect one &&
316 grep "new blank line at EOF" error
319 test_expect_success 'applying beyond EOF requires one non-blank context line' '
320 test_write_lines "" "" "" "" >one &&
321 git add one &&
322 echo b >>one &&
323 git diff -- one >patch &&
325 git checkout one &&
326 test_write_lines a "" >one &&
327 cp one expect &&
328 test_must_fail git apply --whitespace=fix patch &&
329 test_cmp expect one &&
330 test_must_fail git apply --ignore-space-change --whitespace=fix patch &&
331 test_cmp expect one
334 test_expect_success 'tons of blanks at EOF should not apply' '
335 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
336 test_write_lines "" "" "" "" || return 1
337 done >one &&
338 git add one &&
339 echo a >>one &&
340 git diff -- one >patch &&
342 >one &&
343 test_must_fail git apply --whitespace=fix patch &&
344 test_must_fail git apply --ignore-space-change --whitespace=fix patch
347 test_expect_success 'missing blank line at end with --whitespace=fix' '
348 echo a >one &&
349 echo >>one &&
350 git add one &&
351 echo b >>one &&
352 cp one expect &&
353 git diff -- one >patch &&
354 echo a >one &&
355 cp one saved-one &&
356 test_must_fail git apply patch &&
357 git apply --whitespace=fix patch &&
358 test_cmp expect one &&
359 mv saved-one one &&
360 git apply --ignore-space-change --whitespace=fix patch &&
361 test_cmp expect one
364 test_expect_success 'two missing blank lines at end with --whitespace=fix' '
365 test_write_lines a "" b c >one &&
366 cp one no-blank-lines &&
367 test_write_lines "" "" >>one &&
368 git add one &&
369 echo d >>one &&
370 cp one expect &&
371 echo >>one &&
372 git diff -- one >patch &&
373 cp no-blank-lines one &&
374 test_must_fail git apply patch &&
375 git apply --whitespace=fix patch &&
376 test_cmp expect one &&
377 mv no-blank-lines one &&
378 test_must_fail git apply patch &&
379 git apply --ignore-space-change --whitespace=fix patch &&
380 test_cmp expect one
383 test_expect_success 'missing blank line at end, insert before end, --whitespace=fix' '
384 test_write_lines a "" >one &&
385 git add one &&
386 test_write_lines b a "" >one &&
387 cp one expect &&
388 git diff -- one >patch &&
389 echo a >one &&
390 test_must_fail git apply patch &&
391 git apply --whitespace=fix patch &&
392 test_cmp expect one
395 test_expect_success 'shrink file with tons of missing blanks at end of file' '
396 test_write_lines a b c >one &&
397 cp one no-blank-lines &&
398 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
399 test_write_lines "" "" "" "" || return 1
400 done >>one &&
401 git add one &&
402 echo a >one &&
403 cp one expect &&
404 git diff -- one >patch &&
405 cp no-blank-lines one &&
406 test_must_fail git apply patch &&
407 git apply --whitespace=fix patch &&
408 test_cmp expect one &&
409 mv no-blank-lines one &&
410 git apply --ignore-space-change --whitespace=fix patch &&
411 test_cmp expect one
414 test_expect_success 'missing blanks at EOF must only match blank lines' '
415 test_write_lines a b >one &&
416 git add one &&
417 test_write_lines c d >>one &&
418 git diff -- one >patch &&
420 echo a >one &&
421 test_must_fail git apply patch &&
422 test_must_fail git apply --whitespace=fix patch &&
423 test_must_fail git apply --ignore-space-change --whitespace=fix patch
426 sed -e's/Z//' >one <<EOF
433 test_expect_success 'missing blank line should match context line with spaces' '
434 git add one &&
435 echo d >>one &&
436 git diff -- one >patch &&
437 test_write_lines a b c >one &&
438 cp one expect &&
439 test_write_lines "" d >>expect &&
440 git add one &&
442 git apply --whitespace=fix patch &&
443 test_cmp expect one
446 sed -e's/Z//' >one <<EOF
453 test_expect_success 'same, but with the --ignore-space-option' '
454 git add one &&
455 echo d >>one &&
456 cp one expect &&
457 git diff -- one >patch &&
458 test_write_lines a b c >one &&
459 git add one &&
461 git checkout-index -f one &&
462 git apply --ignore-space-change --whitespace=fix patch &&
463 test_cmp expect one
466 test_expect_success 'same, but with CR-LF line endings && cr-at-eol set' '
467 git config core.whitespace cr-at-eol &&
468 printf "a\r\n" >one &&
469 printf "b\r\n" >>one &&
470 printf "c\r\n" >>one &&
471 cp one save-one &&
472 printf " \r\n" >>one &&
473 git add one &&
474 printf "d\r\n" >>one &&
475 cp one expect &&
476 git diff -- one >patch &&
477 mv save-one one &&
479 git apply --ignore-space-change --whitespace=fix patch &&
480 test_cmp expect one
483 test_expect_success 'CR-LF line endings && add line && text=auto' '
484 git config --unset core.whitespace &&
485 printf "a\r\n" >one &&
486 cp one save-one &&
487 git add one &&
488 printf "b\r\n" >>one &&
489 cp one expect &&
490 git diff -- one >patch &&
491 mv save-one one &&
492 echo "one text=auto" >.gitattributes &&
493 git apply patch &&
494 test_cmp expect one
497 test_expect_success 'CR-LF line endings && change line && text=auto' '
498 printf "a\r\n" >one &&
499 cp one save-one &&
500 git add one &&
501 printf "b\r\n" >one &&
502 cp one expect &&
503 git diff -- one >patch &&
504 mv save-one one &&
505 echo "one text=auto" >.gitattributes &&
506 git apply patch &&
507 test_cmp expect one
510 test_expect_success 'LF in repo, CRLF in worktree && change line && text=auto' '
511 printf "a\n" >one &&
512 git add one &&
513 printf "b\r\n" >one &&
514 git diff -- one >patch &&
515 printf "a\r\n" >one &&
516 echo "one text=auto" >.gitattributes &&
517 git -c core.eol=CRLF apply patch &&
518 printf "b\r\n" >expect &&
519 test_cmp expect one
522 test_expect_success 'whitespace=fix to expand' '
523 qz_to_tab_space >preimage <<-\EOF &&
527 ZZZZZZZZZZZZZZZZd
532 qz_to_tab_space >patch <<-\EOF &&
533 diff --git a/preimage b/preimage
534 --- a/preimage
535 +++ b/preimage
536 @@ -1,7 +1,6 @@
540 -QQd
545 git -c core.whitespace=tab-in-indent apply --whitespace=fix patch
548 test_expect_success 'whitespace check skipped for excluded paths' '
549 git config core.whitespace blank-at-eol &&
550 >used &&
551 >unused &&
552 git add used unused &&
553 echo "used" >used &&
554 echo "unused " >unused &&
555 git diff-files -p used unused >patch &&
556 git apply --include=used --stat --whitespace=error <patch
559 test_done