gitweb/lib - Use locking to avoid 'cache miss stampede' problem
[git/jnareb-git.git] / t / t4124-apply-ws-rule.sh
blob61bfc569c37eefa6dba4dd6f26513c61d71cfb9c
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 test_cmp file target
92 test_expect_success 'whitespace=warn, default rule' '
94 apply_patch --whitespace=warn &&
95 test_cmp 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 test_cmp 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 test_cmp file target
124 for t in - ''
126 case "$t" in '') tt='!' ;; *) tt= ;; esac
127 for s in - ''
129 case "$s" in '') ts='@' ;; *) ts= ;; esac
130 for i in - ''
132 case "$i" in '') ti='#' ;; *) ti= ;; esac
133 for h in - ''
135 [ -z "$h$i" ] && continue
136 case "$h" in '') th='%' ;; *) th= ;; esac
137 rule=${t}trailing,${s}space,${i}indent,${h}tab
139 rm -f .gitattributes
140 test_expect_success "rule=$rule" '
141 git config core.whitespace "$rule" &&
142 test_fix "$tt$ts$ti$th"
145 test_expect_success "rule=$rule (attributes)" '
146 git config --unset core.whitespace &&
147 echo "target whitespace=$rule" >.gitattributes &&
148 test_fix "$tt$ts$ti$th"
151 done
152 done
153 done
154 done
156 create_patch () {
157 sed -e "s/_/ /" <<-\EOF
158 diff --git a/target b/target
159 index e69de29..8bd6648 100644
160 --- a/target
161 +++ b/target
162 @@ -0,0 +1,3 @@
163 +An empty line follows
165 +A line with trailing whitespace and no newline_
166 \ No newline at end of file
170 test_expect_success 'trailing whitespace & no newline at the end of file' '
171 >target &&
172 create_patch >patch-file &&
173 git apply --whitespace=fix patch-file &&
174 grep "newline$" target &&
175 grep "^$" target
178 test_expect_success 'blank at EOF with --whitespace=fix (1)' '
179 test_might_fail git config --unset core.whitespace &&
180 rm -f .gitattributes &&
182 { echo a; echo b; echo c; } >one &&
183 git add one &&
184 { echo a; echo b; echo c; } >expect &&
185 { cat expect; echo; } >one &&
186 git diff -- one >patch &&
188 git checkout one &&
189 git apply --whitespace=fix patch &&
190 test_cmp expect one
193 test_expect_success 'blank at EOF with --whitespace=fix (2)' '
194 { echo a; echo b; echo c; } >one &&
195 git add one &&
196 { echo a; echo c; } >expect &&
197 { cat expect; echo; echo; } >one &&
198 git diff -- one >patch &&
200 git checkout one &&
201 git apply --whitespace=fix patch &&
202 test_cmp expect one
205 test_expect_success 'blank at EOF with --whitespace=fix (3)' '
206 { echo a; echo b; echo; } >one &&
207 git add one &&
208 { echo a; echo c; echo; } >expect &&
209 { cat expect; echo; echo; } >one &&
210 git diff -- one >patch &&
212 git checkout one &&
213 git apply --whitespace=fix patch &&
214 test_cmp expect one
217 test_expect_success 'blank at end of hunk, not at EOF with --whitespace=fix' '
218 { echo a; echo b; echo; echo; echo; echo; echo; echo d; } >one &&
219 git add one &&
220 { echo a; echo c; echo; echo; echo; echo; echo; echo; echo d; } >expect &&
221 cp expect one &&
222 git diff -- one >patch &&
224 git checkout one &&
225 git apply --whitespace=fix patch &&
226 test_cmp expect one
229 test_expect_success 'blank at EOF with --whitespace=warn' '
230 { echo a; echo b; echo c; } >one &&
231 git add one &&
232 echo >>one &&
233 cat one >expect &&
234 git diff -- one >patch &&
236 git checkout one &&
237 git apply --whitespace=warn patch 2>error &&
238 test_cmp expect one &&
239 grep "new blank line at EOF" error
242 test_expect_success 'blank at EOF with --whitespace=error' '
243 { echo a; echo b; echo c; } >one &&
244 git add one &&
245 cat one >expect &&
246 echo >>one &&
247 git diff -- one >patch &&
249 git checkout one &&
250 test_must_fail git apply --whitespace=error patch 2>error &&
251 test_cmp expect one &&
252 grep "new blank line at EOF" error
255 test_expect_success 'blank but not empty at EOF' '
256 { echo a; echo b; echo c; } >one &&
257 git add one &&
258 echo " " >>one &&
259 cat one >expect &&
260 git diff -- one >patch &&
262 git checkout one &&
263 git apply --whitespace=warn patch 2>error &&
264 test_cmp expect one &&
265 grep "new blank line at EOF" error
268 test_expect_success 'applying beyond EOF requires one non-blank context line' '
269 { echo; echo; echo; echo; } >one &&
270 git add one &&
271 { echo b; } >>one &&
272 git diff -- one >patch &&
274 git checkout one &&
275 { echo a; echo; } >one &&
276 cp one expect &&
277 test_must_fail git apply --whitespace=fix patch &&
278 test_cmp one expect &&
279 test_must_fail git apply --ignore-space-change --whitespace=fix patch &&
280 test_cmp one expect
283 test_expect_success 'tons of blanks at EOF should not apply' '
284 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
285 echo; echo; echo; echo;
286 done >one &&
287 git add one &&
288 echo a >>one &&
289 git diff -- one >patch &&
291 >one &&
292 test_must_fail git apply --whitespace=fix patch &&
293 test_must_fail git apply --ignore-space-change --whitespace=fix patch
296 test_expect_success 'missing blank line at end with --whitespace=fix' '
297 echo a >one &&
298 echo >>one &&
299 git add one &&
300 echo b >>one &&
301 cp one expect &&
302 git diff -- one >patch &&
303 echo a >one &&
304 cp one saved-one &&
305 test_must_fail git apply patch &&
306 git apply --whitespace=fix patch &&
307 test_cmp one expect &&
308 mv saved-one one &&
309 git apply --ignore-space-change --whitespace=fix patch &&
310 test_cmp one expect
313 test_expect_success 'two missing blank lines at end with --whitespace=fix' '
314 { echo a; echo; echo b; echo c; } >one &&
315 cp one no-blank-lines &&
316 { echo; echo; } >>one &&
317 git add one &&
318 echo d >>one &&
319 cp one expect &&
320 echo >>one &&
321 git diff -- one >patch &&
322 cp no-blank-lines one &&
323 test_must_fail git apply patch &&
324 git apply --whitespace=fix patch &&
325 test_cmp one expect &&
326 mv no-blank-lines one &&
327 test_must_fail git apply patch &&
328 git apply --ignore-space-change --whitespace=fix patch &&
329 test_cmp one expect
332 test_expect_success 'missing blank line at end, insert before end, --whitespace=fix' '
333 { echo a; echo; } >one &&
334 git add one &&
335 { echo b; echo a; echo; } >one &&
336 cp one expect &&
337 git diff -- one >patch &&
338 echo a >one &&
339 test_must_fail git apply patch &&
340 git apply --whitespace=fix patch &&
341 test_cmp one expect
344 test_expect_success 'shrink file with tons of missing blanks at end of file' '
345 { echo a; echo b; echo c; } >one &&
346 cp one no-blank-lines &&
347 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
348 echo; echo; echo; echo;
349 done >>one &&
350 git add one &&
351 echo a >one &&
352 cp one expect &&
353 git diff -- one >patch &&
354 cp no-blank-lines one &&
355 test_must_fail git apply patch &&
356 git apply --whitespace=fix patch &&
357 test_cmp one expect &&
358 mv no-blank-lines one &&
359 git apply --ignore-space-change --whitespace=fix patch &&
360 test_cmp one expect
363 test_expect_success 'missing blanks at EOF must only match blank lines' '
364 { echo a; echo b; } >one &&
365 git add one &&
366 { echo c; echo d; } >>one &&
367 git diff -- one >patch &&
369 echo a >one &&
370 test_must_fail git apply patch &&
371 test_must_fail git apply --whitespace=fix patch &&
372 test_must_fail git apply --ignore-space-change --whitespace=fix patch
375 sed -e's/Z//' >one <<EOF
382 test_expect_success 'missing blank line should match context line with spaces' '
383 git add one &&
384 echo d >>one &&
385 git diff -- one >patch &&
386 { echo a; echo b; echo c; } >one &&
387 cp one expect &&
388 { echo; echo d; } >>expect &&
389 git add one &&
391 git apply --whitespace=fix patch &&
392 test_cmp one expect
395 sed -e's/Z//' >one <<EOF
402 test_expect_success 'same, but with the --ignore-space-option' '
403 git add one &&
404 echo d >>one &&
405 cp one expect &&
406 git diff -- one >patch &&
407 { echo a; echo b; echo c; } >one &&
408 git add one &&
410 git checkout-index -f one &&
411 git apply --ignore-space-change --whitespace=fix patch &&
412 test_cmp one expect
415 test_expect_success 'same, but with CR-LF line endings && cr-at-eol set' '
416 git config core.whitespace cr-at-eol &&
417 printf "a\r\n" >one &&
418 printf "b\r\n" >>one &&
419 printf "c\r\n" >>one &&
420 cp one save-one &&
421 printf " \r\n" >>one &&
422 git add one &&
423 printf "d\r\n" >>one &&
424 cp one expect &&
425 git diff -- one >patch &&
426 mv save-one 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 unset' '
433 git config --unset core.whitespace &&
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 cp one expect &&
441 printf "d\r\n" >>one &&
442 git diff -- one >patch &&
443 mv save-one one &&
444 echo d >>expect &&
446 git apply --ignore-space-change --whitespace=fix patch &&
447 test_cmp one expect
450 test_done