3 test_description='add -i basic tests'
5 . "$TEST_DIRECTORY"/lib-terminal.sh
7 if ! test_have_prereq PERL
9 skip_all='skipping add -i tests, perl not available'
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 /' \
23 test_cmp "$1.filtered" "$2.filtered"
26 test_expect_success 'setup (initial)' '
32 test_expect_success 'status works (initial)' '
33 git add -i </dev/null >output &&
34 grep "+1/-0 *+2/-0 file" output
37 test_expect_success 'setup expected' '
40 index 0000000..d95f3ad
48 test_expect_success 'diff works (initial)' '
49 test_write_lines d 1 | git add -i >output &&
50 sed -ne "/new file/,/content/p" <output >diff &&
51 diff_cmp expected diff
53 test_expect_success 'revert works (initial)' '
55 test_write_lines r 1 | git add -i &&
56 git ls-files >output &&
60 test_expect_success 'setup (commit)' '
61 echo baseline >file &&
63 git commit -m commit &&
64 echo content >>file &&
69 test_expect_success 'status works (commit)' '
70 git add -i </dev/null >output &&
71 grep "+1/-0 *+2/-0 file" output
74 test_expect_success 'setup expected' '
76 index 180b47c..b6f2c08 100644
85 test_expect_success 'diff works (commit)' '
86 test_write_lines d 1 | git add -i >output &&
87 sed -ne "/^index/,/content/p" <output >diff &&
88 diff_cmp expected diff
90 test_expect_success 'revert works (commit)' '
92 test_write_lines r 1 | git add -i &&
93 git add -i </dev/null >output &&
94 grep "unchanged *+3/-0 file" output
98 test_expect_success 'setup expected' '
103 test_expect_success 'dummy edit works' '
105 test_write_lines e a | git add -p &&
107 diff_cmp expected diff
110 test_expect_success 'setup patch' '
120 test_expect_success 'setup fake editor' '
121 write_script "fake_editor.sh" <<-\EOF &&
122 mv -f "$1" oldpatch &&
125 test_set_editor "$(pwd)/fake_editor.sh"
128 test_expect_success 'bad edit rejected' '
130 test_write_lines e n d | git add -p >output &&
131 grep "hunk does not apply" output
134 test_expect_success 'setup patch' '
141 test_expect_success 'garbage edit rejected' '
143 test_write_lines e n d | git add -p >output &&
144 grep "hunk does not apply" output
147 test_expect_success 'setup patch' '
157 test_expect_success 'setup expected' '
158 cat >expected <<-\EOF
159 diff --git a/file b/file
160 index b5dd6c9..f910ae9 100644
172 test_expect_success 'real edit works' '
173 test_write_lines e n d | git add -p &&
175 diff_cmp expected output
178 test_expect_success 'setup file' '
179 test_write_lines a "" b "" c >file &&
181 test_write_lines a "" d "" c >file
184 test_expect_success 'setup patch' '
198 test_expect_success 'setup expected' '
200 diff --git a/file b/file
201 index b5dd6c9..f910ae9 100644
214 test_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 &&
218 diff_cmp expected output
221 test_expect_success 'skip files similarly as commit -a' '
223 echo file >.gitignore &&
224 echo changed >file &&
225 echo y | git add -p file &&
228 git commit -am commit &&
229 git diff >expected &&
230 diff_cmp expected output &&
231 git reset --hard HEAD^
235 test_expect_success FILEMODE 'patch does not affect mode' '
237 echo content >>file &&
239 printf "n\\ny\\n" | git add -p &&
240 git show :file | grep content &&
241 git diff file | grep "new mode"
244 test_expect_success FILEMODE 'stage mode but not hunk' '
246 echo content >>file &&
248 printf "y\\nn\\n" | git add -p &&
249 git diff --cached file | grep "new mode" &&
250 git diff file | grep "+content"
254 test_expect_success FILEMODE 'stage mode and hunk' '
256 echo content >>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)"
264 # end of tests disabled when filemode is not usable
266 test_expect_success 'setup again' '
268 test_chmod +x file &&
272 # Write the patch file with a new line at the top and bottom
273 test_expect_success 'setup patch' '
275 index 180b47c..b6f2c08 100644
283 \ No newline at end of file
287 # Expected output, diff is similar to the patch but w/ diff at the top
288 test_expect_success 'setup expected' '
289 echo diff --git a/file b/file >expected &&
290 cat patch |sed "/^index/s/ 100644/ 100755/" >>expected &&
291 cat >expected-output <<-\EOF
299 \ No newline at end of file
308 \ No newline at end of file
312 # Test splitting the first patch, then adding both
313 test_expect_success C_LOCALE_OUTPUT 'add first line works' '
314 git commit -am "clear local changes" &&
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
325 test_expect_success 'setup expected' '
326 cat >expected <<-\EOF
327 diff --git a/non-empty b/non-empty
328 deleted file mode 100644
329 index d95f3ad..0000000
337 test_expect_success 'deleting a non-empty file' '
339 echo content >non-empty &&
341 git commit -m non-empty &&
343 echo y | git add -p non-empty &&
344 git diff --cached >diff &&
345 diff_cmp expected diff
348 test_expect_success 'setup expected' '
349 cat >expected <<-\EOF
350 diff --git a/empty b/empty
351 deleted file mode 100644
352 index e69de29..0000000
356 test_expect_success 'deleting an empty file' '
360 git commit -m empty &&
362 echo y | git add -p empty &&
363 git diff --cached >diff &&
364 diff_cmp expected diff
367 test_expect_success 'split hunk setup' '
369 test_write_lines 10 20 30 40 50 60 >test &&
372 git commit -m test &&
374 test_write_lines 10 15 20 21 22 23 24 30 40 50 60 >test
377 test_expect_success 'split hunk "add -p (edit)"' '
378 # Split, say Edit and do nothing. Then:
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
385 # 2. Correct version applies the (not)edited version, and asks
386 # about the next hunk, against which we say q and program
388 printf "%s\n" s e q n q q |
389 EDITOR=: git add -p &&
394 test_expect_failure 'split hunk "add -p (no, yes, edit)"' '
395 test_write_lines 5 10 20 21 30 31 40 50 60 >test &&
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 &&
406 test_expect_success 'patch mode ignores unmerged entries' '
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
428 git diff --cached >diff &&
429 diff_cmp expected diff
432 test_expect_success TTY 'diffs can be colorized' '
435 echo content >test &&
436 printf y | test_terminal git add -p >output 2>&1 &&
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
443 test_expect_success TTY 'diffFilter filters diff' '
446 echo content >test &&
447 test_config interactive.diffFilter "sed s/^/foo:/" &&
448 printf y | test_terminal git add -p >output 2>&1 &&
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
455 test_expect_success TTY 'detect bogus diffFilter output' '
458 echo content >test &&
459 test_config interactive.diffFilter "echo too-short" &&
460 printf y | test_must_fail test_terminal git add -p
463 test_expect_success 'patch-mode via -i prompts for files' '
468 git add -i <<-\EOF &&
477 git diff --cached --name-only >actual &&
478 diff_cmp expect actual
481 test_expect_success 'add -p handles globs' '
486 echo base >subdir/two.c &&
488 git commit -m base &&
490 echo change >one.c &&
491 echo change >subdir/two.c &&
492 git add -p "*.c" <<-\EOF &&
497 cat >expect <<-\EOF &&
501 git diff --cached --name-only >actual &&
502 test_cmp expect actual
505 test_expect_success 'add -p handles relative paths' '
508 echo base >relpath.c &&
510 git commit -m relpath &&
512 echo change >relpath.c &&
514 git -C subdir add -p .. 2>error <<-\EOF &&
518 test_must_be_empty error &&
520 cat >expect <<-\EOF &&
523 git diff --cached --name-only >actual &&
524 test_cmp expect actual
527 test_expect_success 'add -p does not expand argument lists' '
530 echo content >not-changed &&
531 git add not-changed &&
532 git commit -m "add not-changed file" &&
535 GIT_TRACE=$(pwd)/trace.out git add -p . <<-\EOF &&
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".
543 ! grep -E "^trace: (built-in|exec|run_command): .*not-changed" trace.out
546 test_expect_success 'hunk-editing handles custom comment char' '
548 echo change >>file &&
549 test_config core.commentChar "\$" &&
550 echo e | GIT_EDITOR=true git add -p &&
554 test_expect_success 'add -p works even with color.ui=always' '
556 echo change >>file &&
557 test_config color.ui always &&
558 echo y | git add -p &&
560 git diff --cached --name-only >actual &&
561 test_cmp expect actual
564 test_expect_success 'setup different kinds of dirty submodules' '
565 test_create_repo for-submodules &&
568 test_commit initial &&
569 test_create_repo dirty-head &&
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 &&
581 test_commit updated &&
582 cd ../dirty-both-ways &&
583 test_commit updated &&
584 echo dirty >>initial &&
586 cd ../dirty-otherwise &&
587 echo dirty >>initial &&
590 git -C for-submodules diff-files --name-only >actual &&
591 cat >expected <<-\EOF &&
596 test_cmp expected actual &&
597 git -C for-submodules diff-files --name-only --ignore-submodules=dirty >actual &&
598 cat >expected <<-\EOF &&
602 test_cmp expected actual
605 test_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
612 test_expect_success 'set up pathological context' '
614 test_write_lines a a a a a a a a a a a >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
625 test_expect_success 'add -p works with pathological context lines' '
629 git cat-file blob :a >actual &&
630 test_cmp expected-1 actual
633 test_expect_success 'add -p patch editing works with pathological context lines' '
635 # n q q below is in case edit fails
636 printf "%s\n" e y n q q |
638 git cat-file blob :a >actual &&
639 test_cmp expected-2 actual