]> git.ipfire.org Git - thirdparty/git.git/blob - t/t4124-apply-ws-rule.sh
Merge branch 'jt/v2-fetch-nego-fix'
[thirdparty/git.git] / t / t4124-apply-ws-rule.sh
1 #!/bin/sh
2
3 test_description='core.whitespace rules and git apply'
4
5 . ./test-lib.sh
6
7 prepare_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 (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
35 }
36
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 "$@"
47 }
48
49 test_fix () {
50 # fix should not barf
51 apply_patch --whitespace=fix || return 1
52
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
61 fi
62
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
70
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
77
78 # Get the patch actually applied
79 git diff-files -p target >fixed-patch
80 test -s fixed-patch && return 0
81
82 # Make sure it is complaint-free
83 >target
84 git apply --whitespace=error-all <fixed-patch
85
86 }
87
88 test_expect_success setup '
89
90 >file &&
91 git add file &&
92 prepare_test_file >file &&
93 git diff-files -p >patch &&
94 >target &&
95 git add target
96
97 '
98
99 test_expect_success 'whitespace=nowarn, default rule' '
100
101 apply_patch --whitespace=nowarn &&
102 test_cmp file target
103
104 '
105
106 test_expect_success 'whitespace=warn, default rule' '
107
108 apply_patch --whitespace=warn &&
109 test_cmp file target
110
111 '
112
113 test_expect_success 'whitespace=error-all, default rule' '
114
115 apply_patch ! --whitespace=error-all &&
116 test_must_be_empty target
117
118 '
119
120 test_expect_success 'whitespace=error-all, no rule' '
121
122 git config core.whitespace -trailing,-space-before,-indent &&
123 apply_patch --whitespace=error-all &&
124 test_cmp file target
125
126 '
127
128 test_expect_success 'whitespace=error-all, no rule (attribute)' '
129
130 git config --unset core.whitespace &&
131 echo "target -whitespace" >.gitattributes &&
132 apply_patch --whitespace=error-all &&
133 test_cmp file target
134
135 '
136
137 test_expect_success 'spaces inserted by tab-in-indent' '
138
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>
160 EOF
161 test_cmp expect target
162
163 '
164
165 for t in - ''
166 do
167 case "$t" in '') tt='!' ;; *) tt= ;; esac
168 for s in - ''
169 do
170 case "$s" in '') ts='@' ;; *) ts= ;; esac
171 for i in - ''
172 do
173 case "$i" in '') ti='#' ti16='=';; *) ti= ti16= ;; esac
174 for h in - ''
175 do
176 [ -z "$h$i" ] && continue
177 case "$h" in '') th='%' ;; *) th= ;; esac
178 rule=${t}trailing,${s}space,${i}indent,${h}tab
179
180 rm -f .gitattributes
181 test_expect_success "rule=$rule" '
182 git config core.whitespace "$rule" &&
183 test_fix "$tt$ts$ti$th"
184 '
185
186 test_expect_success "rule=$rule,tabwidth=16" '
187 git config core.whitespace "$rule,tabwidth=16" &&
188 test_fix "$tt$ts$ti16$th"
189 '
190
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"
195 '
196
197 test_expect_success "rule=$rule,tabwidth=16 (attributes)" '
198 echo "target whitespace=$rule,tabwidth=16" >.gitattributes &&
199 test_fix "$tt$ts$ti16$th"
200 '
201
202 done
203 done
204 done
205 done
206
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
215 +
216 +A line with trailing whitespace and no newline_
217 \ No newline at end of file
218 EOF
219 }
220
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
227 '
228
229 test_expect_success 'blank at EOF with --whitespace=fix (1)' '
230 test_might_fail git config --unset core.whitespace &&
231 rm -f .gitattributes &&
232
233 { echo a; echo b; echo c; } >one &&
234 git add one &&
235 { echo a; echo b; echo c; } >expect &&
236 { cat expect; echo; } >one &&
237 git diff -- one >patch &&
238
239 git checkout one &&
240 git apply --whitespace=fix patch &&
241 test_cmp expect one
242 '
243
244 test_expect_success 'blank at EOF with --whitespace=fix (2)' '
245 { echo a; echo b; echo c; } >one &&
246 git add one &&
247 { echo a; echo c; } >expect &&
248 { cat expect; echo; echo; } >one &&
249 git diff -- one >patch &&
250
251 git checkout one &&
252 git apply --whitespace=fix patch &&
253 test_cmp expect one
254 '
255
256 test_expect_success 'blank at EOF with --whitespace=fix (3)' '
257 { echo a; echo b; echo; } >one &&
258 git add one &&
259 { echo a; echo c; echo; } >expect &&
260 { cat expect; echo; echo; } >one &&
261 git diff -- one >patch &&
262
263 git checkout one &&
264 git apply --whitespace=fix patch &&
265 test_cmp expect one
266 '
267
268 test_expect_success 'blank at end of hunk, not at EOF with --whitespace=fix' '
269 { echo a; echo b; echo; echo; echo; echo; echo; echo d; } >one &&
270 git add one &&
271 { echo a; echo c; echo; echo; echo; echo; echo; echo; echo d; } >expect &&
272 cp expect one &&
273 git diff -- one >patch &&
274
275 git checkout one &&
276 git apply --whitespace=fix patch &&
277 test_cmp expect one
278 '
279
280 test_expect_success 'blank at EOF with --whitespace=warn' '
281 { echo a; echo b; echo c; } >one &&
282 git add one &&
283 echo >>one &&
284 cat one >expect &&
285 git diff -- one >patch &&
286
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
291 '
292
293 test_expect_success 'blank at EOF with --whitespace=error' '
294 { echo a; echo b; echo c; } >one &&
295 git add one &&
296 cat one >expect &&
297 echo >>one &&
298 git diff -- one >patch &&
299
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
304 '
305
306 test_expect_success 'blank but not empty at EOF' '
307 { echo a; echo b; echo c; } >one &&
308 git add one &&
309 echo " " >>one &&
310 cat one >expect &&
311 git diff -- one >patch &&
312
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
317 '
318
319 test_expect_success 'applying beyond EOF requires one non-blank context line' '
320 { echo; echo; echo; echo; } >one &&
321 git add one &&
322 { echo b; } >>one &&
323 git diff -- one >patch &&
324
325 git checkout one &&
326 { echo a; echo; } >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
332 '
333
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 echo; echo; echo; echo;
337 done >one &&
338 git add one &&
339 echo a >>one &&
340 git diff -- one >patch &&
341
342 >one &&
343 test_must_fail git apply --whitespace=fix patch &&
344 test_must_fail git apply --ignore-space-change --whitespace=fix patch
345 '
346
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
362 '
363
364 test_expect_success 'two missing blank lines at end with --whitespace=fix' '
365 { echo a; echo; echo b; echo c; } >one &&
366 cp one no-blank-lines &&
367 { echo; echo; } >>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
381 '
382
383 test_expect_success 'missing blank line at end, insert before end, --whitespace=fix' '
384 { echo a; echo; } >one &&
385 git add one &&
386 { echo b; echo a; echo; } >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
393 '
394
395 test_expect_success 'shrink file with tons of missing blanks at end of file' '
396 { echo a; echo b; echo 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 echo; echo; echo; echo;
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
412 '
413
414 test_expect_success 'missing blanks at EOF must only match blank lines' '
415 { echo a; echo b; } >one &&
416 git add one &&
417 { echo c; echo d; } >>one &&
418 git diff -- one >patch &&
419
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
424 '
425
426 sed -e's/Z//' >one <<EOF
427 a
428 b
429 c
430 Z
431 EOF
432
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 { echo a; echo b; echo c; } >one &&
438 cp one expect &&
439 { echo; echo d; } >>expect &&
440 git add one &&
441
442 git apply --whitespace=fix patch &&
443 test_cmp expect one
444 '
445
446 sed -e's/Z//' >one <<EOF
447 a
448 b
449 c
450 Z
451 EOF
452
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 { echo a; echo b; echo c; } >one &&
459 git add one &&
460
461 git checkout-index -f one &&
462 git apply --ignore-space-change --whitespace=fix patch &&
463 test_cmp expect one
464 '
465
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 &&
478
479 git apply --ignore-space-change --whitespace=fix patch &&
480 test_cmp expect one
481 '
482
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
495 '
496
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
508 '
509
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
520 '
521
522 test_expect_success 'whitespace=fix to expand' '
523 qz_to_tab_space >preimage <<-\EOF &&
524 QQa
525 QQb
526 QQc
527 ZZZZZZZZZZZZZZZZd
528 QQe
529 QQf
530 QQg
531 EOF
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 @@
537 QQa
538 QQb
539 QQc
540 -QQd
541 QQe
542 QQf
543 QQg
544 EOF
545 git -c core.whitespace=tab-in-indent apply --whitespace=fix patch
546 '
547
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
557 '
558
559 test_done