]> git.ipfire.org Git - thirdparty/git.git/blame - t/t3701-add-interactive.sh
path.c: don't call the match function without value in trie_find()
[thirdparty/git.git] / t / t3701-add-interactive.sh
CommitLineData
18bc7616
JK
1#!/bin/sh
2
3test_description='add -i basic tests'
4. ./test-lib.sh
8552972b 5. "$TEST_DIRECTORY"/lib-terminal.sh
18bc7616 6
a070221e
JN
7if ! test_have_prereq PERL
8then
9 skip_all='skipping add -i tests, perl not available'
10 test_done
11fi
12
902f414a
PW
13diff_cmp () {
14 for x
15 do
16 sed -e '/^index/s/[0-9a-f]*[1-9a-f][0-9a-f]*\.\./1234567../' \
17 -e '/^index/s/\.\.[0-9a-f]*[1-9a-f][0-9a-f]*/..9abcdef/' \
18 -e '/^index/s/ 00*\.\./ 0000000../' \
19 -e '/^index/s/\.\.00*$/..0000000/' \
20 -e '/^index/s/\.\.00* /..0000000 /' \
21 "$x" >"$x.filtered"
22 done
23 test_cmp "$1.filtered" "$2.filtered"
24}
25
a070221e 26test_expect_success 'setup (initial)' '
18bc7616
JK
27 echo content >file &&
28 git add file &&
29 echo more >>file &&
30 echo lines >>file
31'
a070221e 32test_expect_success 'status works (initial)' '
18bc7616
JK
33 git add -i </dev/null >output &&
34 grep "+1/-0 *+2/-0 file" output
35'
f0459319 36
a070221e 37test_expect_success 'setup expected' '
e4d671c6
PW
38 cat >expected <<-\EOF
39 new file mode 100644
40 index 0000000..d95f3ad
41 --- /dev/null
42 +++ b/file
43 @@ -0,0 +1 @@
44 +content
45 EOF
f0459319
ÆAB
46'
47
a070221e 48test_expect_success 'diff works (initial)' '
0590ff26 49 test_write_lines d 1 | git add -i >output &&
18bc7616 50 sed -ne "/new file/,/content/p" <output >diff &&
902f414a 51 diff_cmp expected diff
18bc7616 52'
a070221e 53test_expect_success 'revert works (initial)' '
18bc7616 54 git add file &&
0590ff26 55 test_write_lines r 1 | git add -i &&
18bc7616
JK
56 git ls-files >output &&
57 ! grep . output
58'
59
a070221e 60test_expect_success 'setup (commit)' '
18bc7616
JK
61 echo baseline >file &&
62 git add file &&
63 git commit -m commit &&
64 echo content >>file &&
65 git add file &&
66 echo more >>file &&
67 echo lines >>file
68'
a070221e 69test_expect_success 'status works (commit)' '
18bc7616
JK
70 git add -i </dev/null >output &&
71 grep "+1/-0 *+2/-0 file" output
72'
f0459319 73
a070221e 74test_expect_success 'setup expected' '
e4d671c6
PW
75 cat >expected <<-\EOF
76 index 180b47c..b6f2c08 100644
77 --- a/file
78 +++ b/file
79 @@ -1 +1,2 @@
80 baseline
81 +content
82 EOF
f0459319
ÆAB
83'
84
a070221e 85test_expect_success 'diff works (commit)' '
0590ff26 86 test_write_lines d 1 | git add -i >output &&
18bc7616 87 sed -ne "/^index/,/content/p" <output >diff &&
902f414a 88 diff_cmp expected diff
18bc7616 89'
a070221e 90test_expect_success 'revert works (commit)' '
18bc7616 91 git add file &&
0590ff26 92 test_write_lines r 1 | git add -i &&
18bc7616
JK
93 git add -i </dev/null >output &&
94 grep "unchanged *+3/-0 file" output
95'
96
f0459319 97
a070221e 98test_expect_success 'setup expected' '
e4d671c6
PW
99 cat >expected <<-\EOF
100 EOF
f0459319
ÆAB
101'
102
a070221e 103test_expect_success 'dummy edit works' '
11489a65 104 test_set_editor : &&
0590ff26 105 test_write_lines e a | git add -p &&
ac083c47 106 git diff > diff &&
902f414a 107 diff_cmp expected diff
ac083c47
TR
108'
109
a070221e 110test_expect_success 'setup patch' '
e4d671c6
PW
111 cat >patch <<-\EOF
112 @@ -1,1 +1,4 @@
113 this
114 +patch
115 -does not
116 apply
117 EOF
f0459319
ÆAB
118'
119
a070221e 120test_expect_success 'setup fake editor' '
11489a65 121 write_script "fake_editor.sh" <<-\EOF &&
e4d671c6
PW
122 mv -f "$1" oldpatch &&
123 mv -f patch "$1"
124 EOF
f0459319
ÆAB
125 test_set_editor "$(pwd)/fake_editor.sh"
126'
127
a070221e 128test_expect_success 'bad edit rejected' '
ac083c47 129 git reset &&
0590ff26 130 test_write_lines e n d | git add -p >output &&
ac083c47
TR
131 grep "hunk does not apply" output
132'
133
a070221e 134test_expect_success 'setup patch' '
e4d671c6
PW
135 cat >patch <<-\EOF
136 this patch
137 is garbage
138 EOF
f0459319
ÆAB
139'
140
a070221e 141test_expect_success 'garbage edit rejected' '
ac083c47 142 git reset &&
0590ff26 143 test_write_lines e n d | git add -p >output &&
ac083c47
TR
144 grep "hunk does not apply" output
145'
146
a070221e 147test_expect_success 'setup patch' '
e4d671c6
PW
148 cat >patch <<-\EOF
149 @@ -1,0 +1,0 @@
150 baseline
151 +content
152 +newcontent
153 +lines
154 EOF
f0459319
ÆAB
155'
156
a070221e 157test_expect_success 'setup expected' '
e4d671c6
PW
158 cat >expected <<-\EOF
159 diff --git a/file b/file
160 index b5dd6c9..f910ae9 100644
161 --- a/file
162 +++ b/file
163 @@ -1,4 +1,4 @@
164 baseline
165 content
166 -newcontent
167 +more
168 lines
169 EOF
f0459319
ÆAB
170'
171
a070221e 172test_expect_success 'real edit works' '
0590ff26 173 test_write_lines e n d | git add -p &&
ac083c47 174 git diff >output &&
902f414a 175 diff_cmp expected output
ac083c47
TR
176'
177
f4d35a6b
PW
178test_expect_success 'setup file' '
179 test_write_lines a "" b "" c >file &&
180 git add file &&
181 test_write_lines a "" d "" c >file
182'
183
184test_expect_success 'setup patch' '
185 SP=" " &&
186 NULL="" &&
187 cat >patch <<-EOF
188 @@ -1,4 +1,4 @@
189 a
190 $NULL
191 -b
192 +f
193 $SP
194 c
195 EOF
196'
197
198test_expect_success 'setup expected' '
199 cat >expected <<-EOF
200 diff --git a/file b/file
201 index b5dd6c9..f910ae9 100644
202 --- a/file
203 +++ b/file
204 @@ -1,5 +1,5 @@
205 a
206 $SP
207 -f
208 +d
209 $SP
210 c
211 EOF
212'
213
214test_expect_success 'edit can strip spaces from empty context lines' '
215 test_write_lines e n q | git add -p 2>error &&
216 test_must_be_empty error &&
217 git diff >output &&
218 diff_cmp expected output
219'
220
a070221e 221test_expect_success 'skip files similarly as commit -a' '
b145b211
PV
222 git reset &&
223 echo file >.gitignore &&
224 echo changed >file &&
225 echo y | git add -p file &&
226 git diff >output &&
227 git reset &&
228 git commit -am commit &&
229 git diff >expected &&
902f414a 230 diff_cmp expected output &&
b145b211
PV
231 git reset --hard HEAD^
232'
233rm -f .gitignore
234
a070221e 235test_expect_success FILEMODE 'patch does not affect mode' '
b717a627
JK
236 git reset --hard &&
237 echo content >>file &&
238 chmod +x file &&
ca724686 239 printf "n\\ny\\n" | git add -p &&
b717a627
JK
240 git show :file | grep content &&
241 git diff file | grep "new mode"
242'
243
a070221e 244test_expect_success FILEMODE 'stage mode but not hunk' '
ca724686
JK
245 git reset --hard &&
246 echo content >>file &&
247 chmod +x file &&
248 printf "y\\nn\\n" | git add -p &&
249 git diff --cached file | grep "new mode" &&
250 git diff file | grep "+content"
251'
252
87ca2eaa 253
a070221e 254test_expect_success FILEMODE 'stage mode and hunk' '
87ca2eaa
KS
255 git reset --hard &&
256 echo content >>file &&
257 chmod +x file &&
258 printf "y\\ny\\n" | git add -p &&
259 git diff --cached file | grep "new mode" &&
260 git diff --cached file | grep "+content" &&
261 test -z "$(git diff file)"
262'
263
26ec126a 264# end of tests disabled when filemode is not usable
ca724686 265
a070221e 266test_expect_success 'setup again' '
32a90233
JS
267 git reset --hard &&
268 test_chmod +x file &&
269 echo content >>file
270'
271
f67182bf 272# Write the patch file with a new line at the top and bottom
a070221e 273test_expect_success 'setup patch' '
e4d671c6
PW
274 cat >patch <<-\EOF
275 index 180b47c..b6f2c08 100644
276 --- a/file
277 +++ b/file
278 @@ -1,2 +1,4 @@
279 +firstline
280 baseline
281 content
282 +lastline
b3e0fcfe 283 \ No newline at end of file
e4d671c6 284 EOF
f0459319
ÆAB
285'
286
b3e0fcfe 287# Expected output, diff is similar to the patch but w/ diff at the top
a070221e 288test_expect_success 'setup expected' '
b3e0fcfe
PW
289 echo diff --git a/file b/file >expected &&
290 cat patch |sed "/^index/s/ 100644/ 100755/" >>expected &&
291 cat >expected-output <<-\EOF
e4d671c6
PW
292 --- a/file
293 +++ b/file
294 @@ -1,2 +1,4 @@
295 +firstline
296 baseline
297 content
298 +lastline
b3e0fcfe
PW
299 \ No newline at end of file
300 @@ -1,2 +1,3 @@
301 +firstline
302 baseline
303 content
304 @@ -1,2 +2,3 @@
305 baseline
306 content
307 +lastline
308 \ No newline at end of file
e4d671c6 309 EOF
f0459319
ÆAB
310'
311
f67182bf 312# Test splitting the first patch, then adding both
b3e0fcfe 313test_expect_success C_LOCALE_OUTPUT 'add first line works' '
f67182bf
MG
314 git commit -am "clear local changes" &&
315 git apply patch &&
b3e0fcfe
PW
316 printf "%s\n" s y y | git add -p file 2>error |
317 sed -n -e "s/^Stage this hunk[^@]*\(@@ .*\)/\1/" \
318 -e "/^[-+@ \\\\]"/p >output &&
319 test_must_be_empty error &&
320 git diff --cached >diff &&
321 diff_cmp expected diff &&
322 test_cmp expected-output output
f67182bf
MG
323'
324
a070221e 325test_expect_success 'setup expected' '
e4d671c6
PW
326 cat >expected <<-\EOF
327 diff --git a/non-empty b/non-empty
328 deleted file mode 100644
329 index d95f3ad..0000000
330 --- a/non-empty
331 +++ /dev/null
332 @@ -1 +0,0 @@
333 -content
334 EOF
f0459319
ÆAB
335'
336
a070221e 337test_expect_success 'deleting a non-empty file' '
8947fdd5
JK
338 git reset --hard &&
339 echo content >non-empty &&
340 git add non-empty &&
341 git commit -m non-empty &&
342 rm non-empty &&
343 echo y | git add -p non-empty &&
344 git diff --cached >diff &&
902f414a 345 diff_cmp expected diff
8947fdd5
JK
346'
347
a070221e 348test_expect_success 'setup expected' '
e4d671c6
PW
349 cat >expected <<-\EOF
350 diff --git a/empty b/empty
351 deleted file mode 100644
352 index e69de29..0000000
353 EOF
f0459319 354'
24ab81ae 355
a070221e 356test_expect_success 'deleting an empty file' '
24ab81ae
JK
357 git reset --hard &&
358 > empty &&
359 git add empty &&
360 git commit -m empty &&
361 rm empty &&
362 echo y | git add -p empty &&
363 git diff --cached >diff &&
902f414a 364 diff_cmp expected diff
24ab81ae
JK
365'
366
a070221e 367test_expect_success 'split hunk setup' '
f3217e2b 368 git reset --hard &&
11489a65 369 test_write_lines 10 20 30 40 50 60 >test &&
f3217e2b
JH
370 git add test &&
371 test_tick &&
372 git commit -m test &&
373
11489a65 374 test_write_lines 10 15 20 21 22 23 24 30 40 50 60 >test
f3217e2b
JH
375'
376
a070221e 377test_expect_success 'split hunk "add -p (edit)"' '
f3217e2b
JH
378 # Split, say Edit and do nothing. Then:
379 #
380 # 1. Broken version results in a patch that does not apply and
381 # only takes [y/n] (edit again) so the first q is discarded
382 # and then n attempts to discard the edit. Repeat q enough
383 # times to get out.
384 #
385 # 2. Correct version applies the (not)edited version, and asks
41ccfdd9 386 # about the next hunk, against which we say q and program
f3217e2b 387 # exits.
416145f0 388 printf "%s\n" s e q n q q |
f3217e2b
JH
389 EDITOR=: git add -p &&
390 git diff >actual &&
391 ! grep "^+15" actual
392'
393
1bf01040 394test_expect_failure 'split hunk "add -p (no, yes, edit)"' '
11489a65 395 test_write_lines 5 10 20 21 30 31 40 50 60 >test &&
1bf01040
MM
396 git reset &&
397 # test sequence is s(plit), n(o), y(es), e(dit)
398 # q n q q is there to make sure we exit at the end.
399 printf "%s\n" s n y e q n q q |
400 EDITOR=: git add -p 2>error &&
401 test_must_be_empty error &&
402 git diff >actual &&
403 ! grep "^+31" actual
404'
405
4066bd67
JK
406test_expect_success 'patch mode ignores unmerged entries' '
407 git reset --hard &&
408 test_commit conflict &&
409 test_commit non-conflict &&
410 git checkout -b side &&
411 test_commit side conflict.t &&
412 git checkout master &&
413 test_commit master conflict.t &&
414 test_must_fail git merge side &&
415 echo changed >non-conflict.t &&
416 echo y | git add -p >output &&
417 ! grep a/conflict.t output &&
418 cat >expected <<-\EOF &&
419 * Unmerged path conflict.t
420 diff --git a/non-conflict.t b/non-conflict.t
421 index f766221..5ea2ed4 100644
422 --- a/non-conflict.t
423 +++ b/non-conflict.t
424 @@ -1 +1 @@
425 -non-conflict
426 +changed
427 EOF
428 git diff --cached >diff &&
902f414a 429 diff_cmp expected diff
4066bd67
JK
430'
431
8552972b 432test_expect_success TTY 'diffs can be colorized' '
55cccf4b
JK
433 git reset --hard &&
434
55cccf4b 435 echo content >test &&
8552972b 436 printf y | test_terminal git add -p >output 2>&1 &&
55cccf4b
JK
437
438 # We do not want to depend on the exact coloring scheme
439 # git uses for diffs, so just check that we saw some kind of color.
440 grep "$(printf "\\033")" output
441'
442
af3570ed
JK
443test_expect_success TTY 'diffFilter filters diff' '
444 git reset --hard &&
445
446 echo content >test &&
447 test_config interactive.diffFilter "sed s/^/foo:/" &&
448 printf y | test_terminal git add -p >output 2>&1 &&
449
450 # avoid depending on the exact coloring or content of the prompts,
451 # and just make sure we saw our diff prefixed
452 grep foo:.*content output
453'
454
42f7d454
JK
455test_expect_success TTY 'detect bogus diffFilter output' '
456 git reset --hard &&
457
458 echo content >test &&
459 test_config interactive.diffFilter "echo too-short" &&
460 printf y | test_must_fail test_terminal git add -p
461'
462
c852bd54
JK
463test_expect_success 'patch-mode via -i prompts for files' '
464 git reset --hard &&
465
466 echo one >file &&
467 echo two >test &&
468 git add -i <<-\EOF &&
469 patch
470 test
471
472 y
473 quit
474 EOF
475
476 echo test >expect &&
477 git diff --cached --name-only >actual &&
902f414a 478 diff_cmp expect actual
c852bd54
JK
479'
480
7288e12c
JK
481test_expect_success 'add -p handles globs' '
482 git reset --hard &&
483
484 mkdir -p subdir &&
485 echo base >one.c &&
486 echo base >subdir/two.c &&
487 git add "*.c" &&
488 git commit -m base &&
489
490 echo change >one.c &&
491 echo change >subdir/two.c &&
492 git add -p "*.c" <<-\EOF &&
493 y
494 y
495 EOF
496
497 cat >expect <<-\EOF &&
498 one.c
499 subdir/two.c
500 EOF
501 git diff --cached --name-only >actual &&
502 test_cmp expect actual
503'
504
be4dbbbe
PS
505test_expect_success 'add -p handles relative paths' '
506 git reset --hard &&
507
508 echo base >relpath.c &&
509 git add "*.c" &&
510 git commit -m relpath &&
511
512 echo change >relpath.c &&
513 mkdir -p subdir &&
514 git -C subdir add -p .. 2>error <<-\EOF &&
515 y
516 EOF
517
518 test_must_be_empty error &&
519
520 cat >expect <<-\EOF &&
521 relpath.c
522 EOF
523 git diff --cached --name-only >actual &&
524 test_cmp expect actual
525'
526
7288e12c
JK
527test_expect_success 'add -p does not expand argument lists' '
528 git reset --hard &&
529
530 echo content >not-changed &&
531 git add not-changed &&
532 git commit -m "add not-changed file" &&
533
534 echo change >file &&
535 GIT_TRACE=$(pwd)/trace.out git add -p . <<-\EOF &&
536 y
537 EOF
538
539 # we know that "file" must be mentioned since we actually
540 # update it, but we want to be sure that our "." pathspec
541 # was not expanded into the argument list of any command.
542 # So look only for "not-changed".
79336116 543 ! grep -E "^trace: (built-in|exec|run_command): .*not-changed" trace.out
7288e12c
JK
544'
545
d85d7ecb
JK
546test_expect_success 'hunk-editing handles custom comment char' '
547 git reset --hard &&
548 echo change >>file &&
549 test_config core.commentChar "\$" &&
550 echo e | GIT_EDITOR=true git add -p &&
551 git diff --exit-code
552'
553
6be4595e
JK
554test_expect_success 'add -p works even with color.ui=always' '
555 git reset --hard &&
556 echo change >>file &&
557 test_config color.ui always &&
558 echo y | git add -p &&
559 echo file >expect &&
560 git diff --cached --name-only >actual &&
561 test_cmp expect actual
562'
563
12434efc
NTND
564test_expect_success 'setup different kinds of dirty submodules' '
565 test_create_repo for-submodules &&
566 (
567 cd for-submodules &&
568 test_commit initial &&
569 test_create_repo dirty-head &&
570 (
571 cd dirty-head &&
572 test_commit initial
573 ) &&
574 cp -R dirty-head dirty-otherwise &&
575 cp -R dirty-head dirty-both-ways &&
576 git add dirty-head &&
577 git add dirty-otherwise dirty-both-ways &&
578 git commit -m initial &&
579
580 cd dirty-head &&
581 test_commit updated &&
582 cd ../dirty-both-ways &&
583 test_commit updated &&
584 echo dirty >>initial &&
585 : >untracked &&
586 cd ../dirty-otherwise &&
587 echo dirty >>initial &&
588 : >untracked
589 ) &&
590 git -C for-submodules diff-files --name-only >actual &&
591 cat >expected <<-\EOF &&
592 dirty-both-ways
593 dirty-head
594 dirty-otherwise
595 EOF
596 test_cmp expected actual &&
597 git -C for-submodules diff-files --name-only --ignore-submodules=dirty >actual &&
598 cat >expected <<-\EOF &&
599 dirty-both-ways
600 dirty-head
601 EOF
602 test_cmp expected actual
603'
604
605test_expect_success 'status ignores dirty submodules (except HEAD)' '
606 git -C for-submodules add -i </dev/null >output &&
607 grep dirty-head output &&
608 grep dirty-both-ways output &&
609 ! grep dirty-otherwise output
610'
611
23fea4c2
PW
612test_expect_success 'set up pathological context' '
613 git reset --hard &&
614 test_write_lines a a a a a a a a a a a >a &&
615 git add a &&
616 git commit -m a &&
617 test_write_lines c b a a a a a a a b a a a a >a &&
618 test_write_lines a a a a a a a b a a a a >expected-1 &&
619 test_write_lines b a a a a a a a b a a a a >expected-2 &&
620 # check editing can cope with missing header and deleted context lines
621 # as well as changes to other lines
622 test_write_lines +b " a" >patch
623'
624
fecc6f3a 625test_expect_success 'add -p works with pathological context lines' '
23fea4c2
PW
626 git reset &&
627 printf "%s\n" n y |
628 git add -p &&
629 git cat-file blob :a >actual &&
630 test_cmp expected-1 actual
631'
632
2b8ea7f3 633test_expect_success 'add -p patch editing works with pathological context lines' '
23fea4c2
PW
634 git reset &&
635 # n q q below is in case edit fails
636 printf "%s\n" e y n q q |
637 git add -p &&
638 git cat-file blob :a >actual &&
639 test_cmp expected-2 actual
640'
641
2bd69b90
PW
642test_expect_success 'checkout -p works with pathological context lines' '
643 test_write_lines a a a a a a >a &&
644 git add a &&
645 test_write_lines a b a b a b a b a b a > a&&
646 test_write_lines s n n y q | git checkout -p &&
647 test_write_lines a b a b a a b a b a >expect &&
648 test_cmp expect a
649'
18bc7616 650test_done