negative-refspec: fix segfault on : refspec
[git] / t / t3701-add-interactive.sh
1 #!/bin/sh
2
3 test_description='add -i basic tests'
4 . ./test-lib.sh
5 . "$TEST_DIRECTORY"/lib-terminal.sh
6
7 if ! test_have_prereq PERL
8 then
9         skip_all='skipping add -i tests, perl not available'
10         test_done
11 fi
12
13 diff_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
26 # This function uses a trick to manipulate the interactive add to use color:
27 # the `want_color()` function special-cases the situation where a pager was
28 # spawned and Git now wants to output colored text: to detect that situation,
29 # the environment variable `GIT_PAGER_IN_USE` is set. However, color is
30 # suppressed despite that environment variable if the `TERM` variable
31 # indicates a dumb terminal, so we set that variable, too.
32
33 force_color () {
34         # The first element of $@ may be a shell function, as a result POSIX
35         # does not guarantee that "one-shot assignment" will not persist after
36         # the function call. Thus, we prevent these variables from escaping
37         # this function's context with this subshell.
38         (
39                 GIT_PAGER_IN_USE=true &&
40                 TERM=vt100 &&
41                 export GIT_PAGER_IN_USE TERM &&
42                 "$@"
43         )
44 }
45
46 test_expect_success 'setup (initial)' '
47         echo content >file &&
48         git add file &&
49         echo more >>file &&
50         echo lines >>file
51 '
52 test_expect_success 'status works (initial)' '
53         git add -i </dev/null >output &&
54         grep "+1/-0 *+2/-0 file" output
55 '
56
57 test_expect_success 'setup expected' '
58         cat >expected <<-\EOF
59         new file mode 100644
60         index 0000000..d95f3ad
61         --- /dev/null
62         +++ b/file
63         @@ -0,0 +1 @@
64         +content
65         EOF
66 '
67
68 test_expect_success 'diff works (initial)' '
69         test_write_lines d 1 | git add -i >output &&
70         sed -ne "/new file/,/content/p" <output >diff &&
71         diff_cmp expected diff
72 '
73 test_expect_success 'revert works (initial)' '
74         git add file &&
75         test_write_lines r 1 | git add -i &&
76         git ls-files >output &&
77         ! grep . output
78 '
79
80 test_expect_success 'add untracked (multiple)' '
81         test_when_finished "git reset && rm [1-9]" &&
82         touch $(test_seq 9) &&
83         test_write_lines a "2-5 8-" | git add -i -- [1-9] &&
84         test_write_lines 2 3 4 5 8 9 >expected &&
85         git ls-files [1-9] >output &&
86         test_cmp expected output
87 '
88
89 test_expect_success 'setup (commit)' '
90         echo baseline >file &&
91         git add file &&
92         git commit -m commit &&
93         echo content >>file &&
94         git add file &&
95         echo more >>file &&
96         echo lines >>file
97 '
98 test_expect_success 'status works (commit)' '
99         git add -i </dev/null >output &&
100         grep "+1/-0 *+2/-0 file" output
101 '
102
103 test_expect_success 'setup expected' '
104         cat >expected <<-\EOF
105         index 180b47c..b6f2c08 100644
106         --- a/file
107         +++ b/file
108         @@ -1 +1,2 @@
109          baseline
110         +content
111         EOF
112 '
113
114 test_expect_success 'diff works (commit)' '
115         test_write_lines d 1 | git add -i >output &&
116         sed -ne "/^index/,/content/p" <output >diff &&
117         diff_cmp expected diff
118 '
119 test_expect_success 'revert works (commit)' '
120         git add file &&
121         test_write_lines r 1 | git add -i &&
122         git add -i </dev/null >output &&
123         grep "unchanged *+3/-0 file" output
124 '
125
126 test_expect_success 'setup expected' '
127         cat >expected <<-\EOF
128         EOF
129 '
130
131 test_expect_success 'dummy edit works' '
132         test_set_editor : &&
133         test_write_lines e a | git add -p &&
134         git diff > diff &&
135         diff_cmp expected diff
136 '
137
138 test_expect_success 'setup patch' '
139         cat >patch <<-\EOF
140         @@ -1,1 +1,4 @@
141          this
142         +patch
143         -does not
144          apply
145         EOF
146 '
147
148 test_expect_success 'setup fake editor' '
149         write_script "fake_editor.sh" <<-\EOF &&
150         mv -f "$1" oldpatch &&
151         mv -f patch "$1"
152         EOF
153         test_set_editor "$(pwd)/fake_editor.sh"
154 '
155
156 test_expect_success 'bad edit rejected' '
157         git reset &&
158         test_write_lines e n d | git add -p >output &&
159         grep "hunk does not apply" output
160 '
161
162 test_expect_success 'setup patch' '
163         cat >patch <<-\EOF
164         this patch
165         is garbage
166         EOF
167 '
168
169 test_expect_success 'garbage edit rejected' '
170         git reset &&
171         test_write_lines e n d | git add -p >output &&
172         grep "hunk does not apply" output
173 '
174
175 test_expect_success 'setup patch' '
176         cat >patch <<-\EOF
177         @@ -1,0 +1,0 @@
178          baseline
179         +content
180         +newcontent
181         +lines
182         EOF
183 '
184
185 test_expect_success 'setup expected' '
186         cat >expected <<-\EOF
187         diff --git a/file b/file
188         index b5dd6c9..f910ae9 100644
189         --- a/file
190         +++ b/file
191         @@ -1,4 +1,4 @@
192          baseline
193          content
194         -newcontent
195         +more
196          lines
197         EOF
198 '
199
200 test_expect_success 'real edit works' '
201         test_write_lines e n d | git add -p &&
202         git diff >output &&
203         diff_cmp expected output
204 '
205
206 test_expect_success 'setup file' '
207         test_write_lines a "" b "" c >file &&
208         git add file &&
209         test_write_lines a "" d "" c >file
210 '
211
212 test_expect_success 'setup patch' '
213         SP=" " &&
214         NULL="" &&
215         cat >patch <<-EOF
216         @@ -1,4 +1,4 @@
217          a
218         $NULL
219         -b
220         +f
221         $SP
222         c
223         EOF
224 '
225
226 test_expect_success 'setup expected' '
227         cat >expected <<-EOF
228         diff --git a/file b/file
229         index b5dd6c9..f910ae9 100644
230         --- a/file
231         +++ b/file
232         @@ -1,5 +1,5 @@
233          a
234         $SP
235         -f
236         +d
237         $SP
238          c
239         EOF
240 '
241
242 test_expect_success 'edit can strip spaces from empty context lines' '
243         test_write_lines e n q | git add -p 2>error &&
244         test_must_be_empty error &&
245         git diff >output &&
246         diff_cmp expected output
247 '
248
249 test_expect_success 'skip files similarly as commit -a' '
250         git reset &&
251         echo file >.gitignore &&
252         echo changed >file &&
253         echo y | git add -p file &&
254         git diff >output &&
255         git reset &&
256         git commit -am commit &&
257         git diff >expected &&
258         diff_cmp expected output &&
259         git reset --hard HEAD^
260 '
261 rm -f .gitignore
262
263 test_expect_success FILEMODE 'patch does not affect mode' '
264         git reset --hard &&
265         echo content >>file &&
266         chmod +x file &&
267         printf "n\\ny\\n" | git add -p &&
268         git show :file | grep content &&
269         git diff file | grep "new mode"
270 '
271
272 test_expect_success FILEMODE 'stage mode but not hunk' '
273         git reset --hard &&
274         echo content >>file &&
275         chmod +x file &&
276         printf "y\\nn\\n" | git add -p &&
277         git diff --cached file | grep "new mode" &&
278         git diff          file | grep "+content"
279 '
280
281
282 test_expect_success FILEMODE 'stage mode and hunk' '
283         git reset --hard &&
284         echo content >>file &&
285         chmod +x file &&
286         printf "y\\ny\\n" | git add -p &&
287         git diff --cached file | grep "new mode" &&
288         git diff --cached file | grep "+content" &&
289         test -z "$(git diff file)"
290 '
291
292 # end of tests disabled when filemode is not usable
293
294 test_expect_success 'different prompts for mode change/deleted' '
295         git reset --hard &&
296         >file &&
297         >deleted &&
298         git add --chmod=+x file deleted &&
299         echo changed >file &&
300         rm deleted &&
301         test_write_lines n n n |
302         git -c core.filemode=true add -p >actual &&
303         sed -n "s/^\(([0-9/]*) Stage .*?\).*/\1/p" actual >actual.filtered &&
304         cat >expect <<-\EOF &&
305         (1/1) Stage deletion [y,n,q,a,d,?]?
306         (1/2) Stage mode change [y,n,q,a,d,j,J,g,/,?]?
307         (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]?
308         EOF
309         test_cmp expect actual.filtered
310 '
311
312 test_expect_success 'correct message when there is nothing to do' '
313         git reset --hard &&
314         git add -p 2>err &&
315         test_i18ngrep "No changes" err &&
316         printf "\\0123" >binary &&
317         git add binary &&
318         printf "\\0abc" >binary &&
319         git add -p 2>err &&
320         test_i18ngrep "Only binary files changed" err
321 '
322
323 test_expect_success 'setup again' '
324         git reset --hard &&
325         test_chmod +x file &&
326         echo content >>file
327 '
328
329 # Write the patch file with a new line at the top and bottom
330 test_expect_success 'setup patch' '
331         cat >patch <<-\EOF
332         index 180b47c..b6f2c08 100644
333         --- a/file
334         +++ b/file
335         @@ -1,2 +1,4 @@
336         +firstline
337          baseline
338          content
339         +lastline
340         \ No newline at end of file
341         EOF
342 '
343
344 # Expected output, diff is similar to the patch but w/ diff at the top
345 test_expect_success 'setup expected' '
346         echo diff --git a/file b/file >expected &&
347         cat patch |sed "/^index/s/ 100644/ 100755/" >>expected &&
348         cat >expected-output <<-\EOF
349         --- a/file
350         +++ b/file
351         @@ -1,2 +1,4 @@
352         +firstline
353          baseline
354          content
355         +lastline
356         \ No newline at end of file
357         @@ -1,2 +1,3 @@
358         +firstline
359          baseline
360          content
361         @@ -1,2 +2,3 @@
362          baseline
363          content
364         +lastline
365         \ No newline at end of file
366         EOF
367 '
368
369 # Test splitting the first patch, then adding both
370 test_expect_success C_LOCALE_OUTPUT 'add first line works' '
371         git commit -am "clear local changes" &&
372         git apply patch &&
373         printf "%s\n" s y y | git add -p file 2>error |
374                 sed -n -e "s/^([1-2]\/[1-2]) Stage this hunk[^@]*\(@@ .*\)/\1/" \
375                        -e "/^[-+@ \\\\]"/p  >output &&
376         test_must_be_empty error &&
377         git diff --cached >diff &&
378         diff_cmp expected diff &&
379         test_cmp expected-output output
380 '
381
382 test_expect_success 'setup expected' '
383         cat >expected <<-\EOF
384         diff --git a/non-empty b/non-empty
385         deleted file mode 100644
386         index d95f3ad..0000000
387         --- a/non-empty
388         +++ /dev/null
389         @@ -1 +0,0 @@
390         -content
391         EOF
392 '
393
394 test_expect_success 'deleting a non-empty file' '
395         git reset --hard &&
396         echo content >non-empty &&
397         git add non-empty &&
398         git commit -m non-empty &&
399         rm non-empty &&
400         echo y | git add -p non-empty &&
401         git diff --cached >diff &&
402         diff_cmp expected diff
403 '
404
405 test_expect_success 'setup expected' '
406         cat >expected <<-\EOF
407         diff --git a/empty b/empty
408         deleted file mode 100644
409         index e69de29..0000000
410         EOF
411 '
412
413 test_expect_success 'deleting an empty file' '
414         git reset --hard &&
415         > empty &&
416         git add empty &&
417         git commit -m empty &&
418         rm empty &&
419         echo y | git add -p empty &&
420         git diff --cached >diff &&
421         diff_cmp expected diff
422 '
423
424 test_expect_success 'adding an empty file' '
425         git init added &&
426         (
427                 cd added &&
428                 test_commit initial &&
429                 >empty &&
430                 git add empty &&
431                 test_tick &&
432                 git commit -m empty &&
433                 git tag added-file &&
434                 git reset --hard HEAD^ &&
435                 test_path_is_missing empty &&
436
437                 echo y | git checkout -p added-file -- >actual &&
438                 test_path_is_file empty &&
439                 test_i18ngrep "Apply addition to index and worktree" actual
440         )
441 '
442
443 test_expect_success 'split hunk setup' '
444         git reset --hard &&
445         test_write_lines 10 20 30 40 50 60 >test &&
446         git add test &&
447         test_tick &&
448         git commit -m test &&
449
450         test_write_lines 10 15 20 21 22 23 24 30 40 50 60 >test
451 '
452
453 test_expect_success 'goto hunk' '
454         test_when_finished "git reset" &&
455         tr _ " " >expect <<-EOF &&
456         (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? + 1:  -1,2 +1,3          +15
457         _ 2:  -2,4 +3,8          +21
458         go to which hunk? @@ -1,2 +1,3 @@
459         _10
460         +15
461         _20
462         (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]?_
463         EOF
464         test_write_lines s y g 1 | git add -p >actual &&
465         tail -n 7 <actual >actual.trimmed &&
466         test_cmp expect actual.trimmed
467 '
468
469 test_expect_success 'navigate to hunk via regex' '
470         test_when_finished "git reset" &&
471         tr _ " " >expect <<-EOF &&
472         (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? @@ -1,2 +1,3 @@
473         _10
474         +15
475         _20
476         (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]?_
477         EOF
478         test_write_lines s y /1,2 | git add -p >actual &&
479         tail -n 5 <actual >actual.trimmed &&
480         test_cmp expect actual.trimmed
481 '
482
483 test_expect_success 'split hunk "add -p (edit)"' '
484         # Split, say Edit and do nothing.  Then:
485         #
486         # 1. Broken version results in a patch that does not apply and
487         # only takes [y/n] (edit again) so the first q is discarded
488         # and then n attempts to discard the edit. Repeat q enough
489         # times to get out.
490         #
491         # 2. Correct version applies the (not)edited version, and asks
492         #    about the next hunk, against which we say q and program
493         #    exits.
494         printf "%s\n" s e     q n q q |
495         EDITOR=: git add -p &&
496         git diff >actual &&
497         ! grep "^+15" actual
498 '
499
500 test_expect_failure 'split hunk "add -p (no, yes, edit)"' '
501         test_write_lines 5 10 20 21 30 31 40 50 60 >test &&
502         git reset &&
503         # test sequence is s(plit), n(o), y(es), e(dit)
504         # q n q q is there to make sure we exit at the end.
505         printf "%s\n" s n y e   q n q q |
506         EDITOR=: git add -p 2>error &&
507         test_must_be_empty error &&
508         git diff >actual &&
509         ! grep "^+31" actual
510 '
511
512 test_expect_success 'split hunk with incomplete line at end' '
513         git reset --hard &&
514         printf "missing LF" >>test &&
515         git add test &&
516         test_write_lines before 10 20 30 40 50 60 70 >test &&
517         git grep --cached missing &&
518         test_write_lines s n y q | git add -p &&
519         test_must_fail git grep --cached missing &&
520         git grep before &&
521         test_must_fail git grep --cached before
522 '
523
524 test_expect_failure 'edit, adding lines to the first hunk' '
525         test_write_lines 10 11 20 30 40 50 51 60 >test &&
526         git reset &&
527         tr _ " " >patch <<-EOF &&
528         @@ -1,5 +1,6 @@
529         _10
530         +11
531         +12
532         _20
533         +21
534         +22
535         _30
536         EOF
537         # test sequence is s(plit), e(dit), n(o)
538         # q n q q is there to make sure we exit at the end.
539         printf "%s\n" s e n   q n q q |
540         EDITOR=./fake_editor.sh git add -p 2>error &&
541         test_must_be_empty error &&
542         git diff --cached >actual &&
543         grep "^+22" actual
544 '
545
546 test_expect_success 'patch mode ignores unmerged entries' '
547         git reset --hard &&
548         test_commit conflict &&
549         test_commit non-conflict &&
550         git checkout -b side &&
551         test_commit side conflict.t &&
552         git checkout master &&
553         test_commit master conflict.t &&
554         test_must_fail git merge side &&
555         echo changed >non-conflict.t &&
556         echo y | git add -p >output &&
557         ! grep a/conflict.t output &&
558         cat >expected <<-\EOF &&
559         * Unmerged path conflict.t
560         diff --git a/non-conflict.t b/non-conflict.t
561         index f766221..5ea2ed4 100644
562         --- a/non-conflict.t
563         +++ b/non-conflict.t
564         @@ -1 +1 @@
565         -non-conflict
566         +changed
567         EOF
568         git diff --cached >diff &&
569         diff_cmp expected diff
570 '
571
572 test_expect_success 'diffs can be colorized' '
573         git reset --hard &&
574
575         echo content >test &&
576         printf y >y &&
577         force_color git add -p >output 2>&1 <y &&
578
579         # We do not want to depend on the exact coloring scheme
580         # git uses for diffs, so just check that we saw some kind of color.
581         grep "$(printf "\\033")" output
582 '
583
584 test_expect_success 'colorized diffs respect diff.wsErrorHighlight' '
585         git reset --hard &&
586
587         echo "old " >test &&
588         git add test &&
589         echo "new " >test &&
590
591         printf y >y &&
592         force_color git -c diff.wsErrorHighlight=all add -p >output.raw 2>&1 <y &&
593         test_decode_color <output.raw >output &&
594         grep "old<" output
595 '
596
597 test_expect_success 'diffFilter filters diff' '
598         git reset --hard &&
599
600         echo content >test &&
601         test_config interactive.diffFilter "sed s/^/foo:/" &&
602         printf y >y &&
603         force_color git add -p >output 2>&1 <y &&
604
605         # avoid depending on the exact coloring or content of the prompts,
606         # and just make sure we saw our diff prefixed
607         grep foo:.*content output
608 '
609
610 test_expect_success 'detect bogus diffFilter output' '
611         git reset --hard &&
612
613         echo content >test &&
614         test_config interactive.diffFilter "sed 1d" &&
615         printf y >y &&
616         force_color test_must_fail git add -p <y
617 '
618
619 test_expect_success 'diff.algorithm is passed to `git diff-files`' '
620         git reset --hard &&
621
622         >file &&
623         git add file &&
624         echo changed >file &&
625         test_must_fail git -c diff.algorithm=bogus add -p 2>err &&
626         test_i18ngrep "error: option diff-algorithm accepts " err
627 '
628
629 test_expect_success 'patch-mode via -i prompts for files' '
630         git reset --hard &&
631
632         echo one >file &&
633         echo two >test &&
634         git add -i <<-\EOF &&
635         patch
636         test
637
638         y
639         quit
640         EOF
641
642         echo test >expect &&
643         git diff --cached --name-only >actual &&
644         diff_cmp expect actual
645 '
646
647 test_expect_success 'add -p handles globs' '
648         git reset --hard &&
649
650         mkdir -p subdir &&
651         echo base >one.c &&
652         echo base >subdir/two.c &&
653         git add "*.c" &&
654         git commit -m base &&
655
656         echo change >one.c &&
657         echo change >subdir/two.c &&
658         git add -p "*.c" <<-\EOF &&
659         y
660         y
661         EOF
662
663         cat >expect <<-\EOF &&
664         one.c
665         subdir/two.c
666         EOF
667         git diff --cached --name-only >actual &&
668         test_cmp expect actual
669 '
670
671 test_expect_success 'add -p handles relative paths' '
672         git reset --hard &&
673
674         echo base >relpath.c &&
675         git add "*.c" &&
676         git commit -m relpath &&
677
678         echo change >relpath.c &&
679         mkdir -p subdir &&
680         git -C subdir add -p .. 2>error <<-\EOF &&
681         y
682         EOF
683
684         test_must_be_empty error &&
685
686         cat >expect <<-\EOF &&
687         relpath.c
688         EOF
689         git diff --cached --name-only >actual &&
690         test_cmp expect actual
691 '
692
693 test_expect_success 'add -p does not expand argument lists' '
694         git reset --hard &&
695
696         echo content >not-changed &&
697         git add not-changed &&
698         git commit -m "add not-changed file" &&
699
700         echo change >file &&
701         GIT_TRACE=$(pwd)/trace.out git add -p . <<-\EOF &&
702         y
703         EOF
704
705         # we know that "file" must be mentioned since we actually
706         # update it, but we want to be sure that our "." pathspec
707         # was not expanded into the argument list of any command.
708         # So look only for "not-changed".
709         ! grep -E "^trace: (built-in|exec|run_command): .*not-changed" trace.out
710 '
711
712 test_expect_success 'hunk-editing handles custom comment char' '
713         git reset --hard &&
714         echo change >>file &&
715         test_config core.commentChar "\$" &&
716         echo e | GIT_EDITOR=true git add -p &&
717         git diff --exit-code
718 '
719
720 test_expect_success 'add -p works even with color.ui=always' '
721         git reset --hard &&
722         echo change >>file &&
723         test_config color.ui always &&
724         echo y | git add -p &&
725         echo file >expect &&
726         git diff --cached --name-only >actual &&
727         test_cmp expect actual
728 '
729
730 test_expect_success 'setup different kinds of dirty submodules' '
731         test_create_repo for-submodules &&
732         (
733                 cd for-submodules &&
734                 test_commit initial &&
735                 test_create_repo dirty-head &&
736                 (
737                         cd dirty-head &&
738                         test_commit initial
739                 ) &&
740                 cp -R dirty-head dirty-otherwise &&
741                 cp -R dirty-head dirty-both-ways &&
742                 git add dirty-head &&
743                 git add dirty-otherwise dirty-both-ways &&
744                 git commit -m initial &&
745
746                 cd dirty-head &&
747                 test_commit updated &&
748                 cd ../dirty-both-ways &&
749                 test_commit updated &&
750                 echo dirty >>initial &&
751                 : >untracked &&
752                 cd ../dirty-otherwise &&
753                 echo dirty >>initial &&
754                 : >untracked
755         ) &&
756         git -C for-submodules diff-files --name-only >actual &&
757         cat >expected <<-\EOF &&
758         dirty-both-ways
759         dirty-head
760         dirty-otherwise
761         EOF
762         test_cmp expected actual &&
763         git -C for-submodules diff-files --name-only --ignore-submodules=dirty >actual &&
764         cat >expected <<-\EOF &&
765         dirty-both-ways
766         dirty-head
767         EOF
768         test_cmp expected actual
769 '
770
771 test_expect_success 'status ignores dirty submodules (except HEAD)' '
772         git -C for-submodules add -i </dev/null >output &&
773         grep dirty-head output &&
774         grep dirty-both-ways output &&
775         ! grep dirty-otherwise output
776 '
777
778 test_expect_success 'set up pathological context' '
779         git reset --hard &&
780         test_write_lines a a a a a a a a a a a >a &&
781         git add a &&
782         git commit -m a &&
783         test_write_lines c b a a a a a a a b a a a a >a &&
784         test_write_lines     a a a a a a a b a a a a >expected-1 &&
785         test_write_lines   b a a a a a a a b a a a a >expected-2 &&
786         # check editing can cope with missing header and deleted context lines
787         # as well as changes to other lines
788         test_write_lines +b " a" >patch
789 '
790
791 test_expect_success 'add -p works with pathological context lines' '
792         git reset &&
793         printf "%s\n" n y |
794         git add -p &&
795         git cat-file blob :a >actual &&
796         test_cmp expected-1 actual
797 '
798
799 test_expect_success 'add -p patch editing works with pathological context lines' '
800         git reset &&
801         # n q q below is in case edit fails
802         printf "%s\n" e y    n q q |
803         git add -p &&
804         git cat-file blob :a >actual &&
805         test_cmp expected-2 actual
806 '
807
808 test_expect_success 'checkout -p works with pathological context lines' '
809         test_write_lines a a a a a a >a &&
810         git add a &&
811         test_write_lines a b a b a b a b a b a >a &&
812         test_write_lines s n n y q | git checkout -p &&
813         test_write_lines a b a b a a b a b a >expect &&
814         test_cmp expect a
815 '
816
817 test_expect_success 'show help from add--helper' '
818         git reset --hard &&
819         cat >expect <<-EOF &&
820
821         <BOLD>*** Commands ***<RESET>
822           1: <BOLD;BLUE>s<RESET>tatus     2: <BOLD;BLUE>u<RESET>pdate     3: <BOLD;BLUE>r<RESET>evert     4: <BOLD;BLUE>a<RESET>dd untracked
823           5: <BOLD;BLUE>p<RESET>atch      6: <BOLD;BLUE>d<RESET>iff       7: <BOLD;BLUE>q<RESET>uit       8: <BOLD;BLUE>h<RESET>elp
824         <BOLD;BLUE>What now<RESET>> <BOLD;RED>status        - show paths with changes<RESET>
825         <BOLD;RED>update        - add working tree state to the staged set of changes<RESET>
826         <BOLD;RED>revert        - revert staged set of changes back to the HEAD version<RESET>
827         <BOLD;RED>patch         - pick hunks and update selectively<RESET>
828         <BOLD;RED>diff          - view diff between HEAD and index<RESET>
829         <BOLD;RED>add untracked - add contents of untracked files to the staged set of changes<RESET>
830         <BOLD>*** Commands ***<RESET>
831           1: <BOLD;BLUE>s<RESET>tatus     2: <BOLD;BLUE>u<RESET>pdate     3: <BOLD;BLUE>r<RESET>evert     4: <BOLD;BLUE>a<RESET>dd untracked
832           5: <BOLD;BLUE>p<RESET>atch      6: <BOLD;BLUE>d<RESET>iff       7: <BOLD;BLUE>q<RESET>uit       8: <BOLD;BLUE>h<RESET>elp
833         <BOLD;BLUE>What now<RESET>>$SP
834         Bye.
835         EOF
836         test_write_lines h | force_color git add -i >actual.colored &&
837         test_decode_color <actual.colored >actual &&
838         test_i18ncmp expect actual
839 '
840
841 test_done