apply --whitespace=fix: fix tab-in-indent
[git/dscho.git] / t / t4124-apply-ws-rule.sh
blobaea052346eab0d2a0b409fdb736279bcfc6b0af2
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
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
36 apply_patch () {
37 >target &&
38 sed -e "s|\([ab]\)/file|\1/target|" <patch |
39 git apply "$@"
42 test_fix () {
43 # fix should not barf
44 apply_patch --whitespace=fix || return 1
46 # find touched lines
47 diff file target | sed -n -e "s/^> //p" >fixed
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
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
64 # Get the patch actually applied
65 git diff-files -p target >fixed-patch
66 test -s fixed-patch && return 0
68 # Make sure it is complaint-free
69 >target
70 git apply --whitespace=error-all <fixed-patch
74 test_expect_success setup '
76 >file &&
77 git add file &&
78 prepare_test_file >file &&
79 git diff-files -p >patch &&
80 >target &&
81 git add target
85 test_expect_success 'whitespace=nowarn, default rule' '
87 apply_patch --whitespace=nowarn &&
88 diff file target
92 test_expect_success 'whitespace=warn, default rule' '
94 apply_patch --whitespace=warn &&
95 diff file target
99 test_expect_success 'whitespace=error-all, default rule' '
101 apply_patch --whitespace=error-all && return 1
102 test -s target && return 1
103 : happy
107 test_expect_success 'whitespace=error-all, no rule' '
109 git config core.whitespace -trailing,-space-before,-indent &&
110 apply_patch --whitespace=error-all &&
111 diff file target
115 test_expect_success 'whitespace=error-all, no rule (attribute)' '
117 git config --unset core.whitespace &&
118 echo "target -whitespace" >.gitattributes &&
119 apply_patch --whitespace=error-all &&
120 diff file target
124 test_expect_success 'spaces inserted by tab-in-indent' '
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>
148 test_cmp expect target
152 for t in - ''
154 case "$t" in '') tt='!' ;; *) tt= ;; esac
155 for s in - ''
157 case "$s" in '') ts='@' ;; *) ts= ;; esac
158 for i in - ''
160 case "$i" in '') ti='#' ;; *) ti= ;; esac
161 for h in - ''
163 [ -z "$h$i" ] && continue
164 case "$h" in '') th='%' ;; *) th= ;; esac
165 rule=${t}trailing,${s}space,${i}indent,${h}tab
167 rm -f .gitattributes
168 test_expect_success "rule=$rule" '
169 git config core.whitespace "$rule" &&
170 test_fix "$tt$ts$ti$th"
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"
179 done
180 done
181 done
182 done
184 create_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
193 +A line with trailing whitespace and no newline_
194 \ No newline at end of file
198 test_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
206 test_expect_success 'blank at EOF with --whitespace=fix (1)' '
207 : these can fail depending on what we did before
208 git config --unset core.whitespace
209 rm -f .gitattributes
211 { echo a; echo b; echo c; } >one &&
212 git add one &&
213 { echo a; echo b; echo c; } >expect &&
214 { cat expect; echo; } >one &&
215 git diff -- one >patch &&
217 git checkout one &&
218 git apply --whitespace=fix patch &&
219 test_cmp expect one
222 test_expect_success 'blank at EOF with --whitespace=fix (2)' '
223 { echo a; echo b; echo c; } >one &&
224 git add one &&
225 { echo a; echo c; } >expect &&
226 { cat expect; echo; echo; } >one &&
227 git diff -- one >patch &&
229 git checkout one &&
230 git apply --whitespace=fix patch &&
231 test_cmp expect one
234 test_expect_success 'blank at EOF with --whitespace=fix (3)' '
235 { echo a; echo b; echo; } >one &&
236 git add one &&
237 { echo a; echo c; echo; } >expect &&
238 { cat expect; echo; echo; } >one &&
239 git diff -- one >patch &&
241 git checkout one &&
242 git apply --whitespace=fix patch &&
243 test_cmp expect one
246 test_expect_success 'blank at end of hunk, not at EOF with --whitespace=fix' '
247 { echo a; echo b; echo; echo; echo; echo; echo; echo d; } >one &&
248 git add one &&
249 { echo a; echo c; echo; echo; echo; echo; echo; echo; echo d; } >expect &&
250 cp expect one &&
251 git diff -- one >patch &&
253 git checkout one &&
254 git apply --whitespace=fix patch &&
255 test_cmp expect one
258 test_expect_success 'blank at EOF with --whitespace=warn' '
259 { echo a; echo b; echo c; } >one &&
260 git add one &&
261 echo >>one &&
262 cat one >expect &&
263 git diff -- one >patch &&
265 git checkout one &&
266 git apply --whitespace=warn patch 2>error &&
267 test_cmp expect one &&
268 grep "new blank line at EOF" error
271 test_expect_success 'blank at EOF with --whitespace=error' '
272 { echo a; echo b; echo c; } >one &&
273 git add one &&
274 cat one >expect &&
275 echo >>one &&
276 git diff -- one >patch &&
278 git checkout one &&
279 test_must_fail git apply --whitespace=error patch 2>error &&
280 test_cmp expect one &&
281 grep "new blank line at EOF" error
284 test_expect_success 'blank but not empty at EOF' '
285 { echo a; echo b; echo c; } >one &&
286 git add one &&
287 echo " " >>one &&
288 cat one >expect &&
289 git diff -- one >patch &&
291 git checkout one &&
292 git apply --whitespace=warn patch 2>error &&
293 test_cmp expect one &&
294 grep "new blank line at EOF" error
297 test_expect_success 'applying beyond EOF requires one non-blank context line' '
298 { echo; echo; echo; echo; } >one &&
299 git add one &&
300 { echo b; } >>one &&
301 git diff -- one >patch &&
303 git checkout one &&
304 { echo a; echo; } >one &&
305 cp one expect &&
306 test_must_fail git apply --whitespace=fix patch &&
307 test_cmp one expect &&
308 test_must_fail git apply --ignore-space-change --whitespace=fix patch &&
309 test_cmp one expect
312 test_expect_success 'tons of blanks at EOF should not apply' '
313 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
314 echo; echo; echo; echo;
315 done >one &&
316 git add one &&
317 echo a >>one &&
318 git diff -- one >patch &&
320 >one &&
321 test_must_fail git apply --whitespace=fix patch &&
322 test_must_fail git apply --ignore-space-change --whitespace=fix patch
325 test_expect_success 'missing blank line at end with --whitespace=fix' '
326 echo a >one &&
327 echo >>one &&
328 git add one &&
329 echo b >>one &&
330 cp one expect &&
331 git diff -- one >patch &&
332 echo a >one &&
333 cp one saved-one &&
334 test_must_fail git apply patch &&
335 git apply --whitespace=fix patch &&
336 test_cmp one expect &&
337 mv saved-one one &&
338 git apply --ignore-space-change --whitespace=fix patch &&
339 test_cmp one expect
342 test_expect_success 'two missing blank lines at end with --whitespace=fix' '
343 { echo a; echo; echo b; echo c; } >one &&
344 cp one no-blank-lines &&
345 { echo; echo; } >>one &&
346 git add one &&
347 echo d >>one &&
348 cp one expect &&
349 echo >>one &&
350 git diff -- one >patch &&
351 cp no-blank-lines one &&
352 test_must_fail git apply patch &&
353 git apply --whitespace=fix patch &&
354 test_cmp one expect &&
355 mv no-blank-lines one &&
356 test_must_fail git apply patch &&
357 git apply --ignore-space-change --whitespace=fix patch &&
358 test_cmp one expect
361 test_expect_success 'shrink file with tons of missing blanks at end of file' '
362 { echo a; echo b; echo c; } >one &&
363 cp one no-blank-lines &&
364 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
365 echo; echo; echo; echo;
366 done >>one &&
367 git add one &&
368 echo a >one &&
369 cp one expect &&
370 git diff -- one >patch &&
371 cp no-blank-lines one &&
372 test_must_fail git apply patch &&
373 git apply --whitespace=fix patch &&
374 test_cmp one expect &&
375 mv no-blank-lines one &&
376 git apply --ignore-space-change --whitespace=fix patch &&
377 test_cmp one expect
380 test_expect_success 'missing blanks at EOF must only match blank lines' '
381 { echo a; echo b; } >one &&
382 git add one &&
383 { echo c; echo d; } >>one &&
384 git diff -- one >patch &&
386 echo a >one &&
387 test_must_fail git apply patch
388 test_must_fail git apply --whitespace=fix patch &&
389 test_must_fail git apply --ignore-space-change --whitespace=fix patch
392 sed -e's/Z//' >one <<EOF
399 test_expect_success 'missing blank line should match context line with spaces' '
400 git add one &&
401 echo d >>one &&
402 git diff -- one >patch &&
403 { echo a; echo b; echo c; } >one &&
404 cp one expect &&
405 { echo; echo d; } >>expect &&
406 git add one &&
408 git apply --whitespace=fix patch &&
409 test_cmp one expect
412 sed -e's/Z//' >one <<EOF
419 test_expect_success 'same, but with the --ignore-space-option' '
420 git add one &&
421 echo d >>one &&
422 cp one expect &&
423 git diff -- one >patch &&
424 { echo a; echo b; echo c; } >one &&
425 git add one &&
427 git checkout-index -f one &&
428 git apply --ignore-space-change --whitespace=fix patch &&
429 test_cmp one expect
432 test_expect_success 'same, but with CR-LF line endings && cr-at-eol set' '
433 git config core.whitespace cr-at-eol &&
434 printf "a\r\n" >one &&
435 printf "b\r\n" >>one &&
436 printf "c\r\n" >>one &&
437 cp one save-one &&
438 printf " \r\n" >>one
439 git add one &&
440 printf "d\r\n" >>one &&
441 cp one expect &&
442 git diff -- one >patch &&
443 mv save-one one &&
445 git apply --ignore-space-change --whitespace=fix patch &&
446 test_cmp one expect
449 test_expect_success 'same, but with CR-LF line endings && cr-at-eol unset' '
450 git config --unset core.whitespace &&
451 printf "a\r\n" >one &&
452 printf "b\r\n" >>one &&
453 printf "c\r\n" >>one &&
454 cp one save-one &&
455 printf " \r\n" >>one
456 git add one &&
457 cp one expect &&
458 printf "d\r\n" >>one &&
459 git diff -- one >patch &&
460 mv save-one one &&
461 echo d >>expect &&
463 git apply --ignore-space-change --whitespace=fix patch &&
464 test_cmp one expect
467 test_done