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'
13 test_expect_success 'setup (initial)' '
19 test_expect_success 'status works (initial)' '
20 git add -i </dev/null >output &&
21 grep "+1/-0 *+2/-0 file" output
24 test_expect_success 'setup expected' '
34 test_expect_success 'diff works (initial)' '
35 (echo d; echo 1) | git add -i >output &&
36 sed -ne /^index/d -e "/new file/,/content/p" <output >diff &&
37 test_cmp expected diff
39 test_expect_success 'revert works (initial)' '
41 (echo r; echo 1) | git add -i &&
42 git ls-files >output &&
46 test_expect_success 'setup (commit)' '
47 echo baseline >file &&
49 git commit -m commit &&
50 echo content >>file &&
55 test_expect_success 'status works (commit)' '
56 git add -i </dev/null >output &&
57 grep "+1/-0 *+2/-0 file" output
60 test_expect_success 'setup expected' '
70 test_expect_success 'diff works (commit)' '
71 (echo d; echo 1) | git add -i >output &&
72 sed -ne "/^---/,/content/p" <output >diff &&
73 test_cmp expected diff
75 test_expect_success 'revert works (commit)' '
77 (echo r; echo 1) | git add -i &&
78 git add -i </dev/null >output &&
79 grep "unchanged *+3/-0 file" output
83 test_expect_success 'setup expected' '
88 test_expect_success 'dummy edit works' '
90 (echo e; echo a) | git add -p &&
91 git diff | sed /^index/d >diff &&
92 test_cmp expected diff
95 test_expect_success 'setup patch' '
105 test_expect_success 'setup fake editor' '
106 write_script "fake_editor.sh" <<-\EOF &&
107 mv -f "$1" oldpatch &&
110 test_set_editor "$(pwd)/fake_editor.sh"
113 test_expect_success 'bad edit rejected' '
115 (echo e; echo n; echo d) | git add -p >output &&
116 grep "hunk does not apply" output
119 test_expect_success 'setup patch' '
126 test_expect_success 'garbage edit rejected' '
128 (echo e; echo n; echo d) | git add -p >output &&
129 grep "hunk does not apply" output
132 test_expect_success 'setup patch' '
142 test_expect_success 'setup expected' '
143 cat >expected <<-\EOF
144 diff --git a/file b/file
156 test_expect_success 'real edit works' '
157 (echo e; echo n; echo d) | git add -p &&
158 git diff | sed /^index/d >output &&
159 test_cmp expected output
162 test_expect_success 'skip files similarly as commit -a' '
164 echo file >.gitignore &&
165 echo changed >file &&
166 echo y | git add -p file &&
167 git diff | sed /^index/d >output &&
169 git commit -am commit &&
170 git diff | sed /^index/d >expected &&
171 test_cmp expected output &&
172 git reset --hard HEAD^
176 test_expect_success FILEMODE 'patch does not affect mode' '
178 echo content >>file &&
180 printf "n\\ny\\n" | git add -p &&
181 git show :file | grep content &&
182 git diff file | grep "new mode"
185 test_expect_success FILEMODE 'stage mode but not hunk' '
187 echo content >>file &&
189 printf "y\\nn\\n" | git add -p &&
190 git diff --cached file | grep "new mode" &&
191 git diff file | grep "+content"
195 test_expect_success FILEMODE 'stage mode and hunk' '
197 echo content >>file &&
199 printf "y\\ny\\n" | git add -p &&
200 git diff --cached file | grep "new mode" &&
201 git diff --cached file | grep "+content" &&
202 test -z "$(git diff file)"
205 # end of tests disabled when filemode is not usable
207 test_expect_success 'setup again' '
209 test_chmod +x file &&
213 # Write the patch file with a new line at the top and bottom
214 test_expect_success 'setup patch' '
223 \ No newline at end of file
227 # Expected output, diff is similar to the patch but w/ diff at the top
228 test_expect_success 'setup expected' '
229 echo diff --git a/file b/file >expected &&
230 cat patch >>expected &&
231 cat >expected-output <<-\EOF
239 \ No newline at end of file
248 \ No newline at end of file
252 # Test splitting the first patch, then adding both
253 test_expect_success C_LOCALE_OUTPUT 'add first line works' '
254 git commit -am "clear local changes" &&
256 printf "%s\n" s y y | git add -p file 2>error |
257 sed -n -e "s/^Stage this hunk[^@]*\(@@ .*\)/\1/" \
258 -e "/^[-+@ \\\\]"/p >output &&
259 test_must_be_empty error &&
260 git diff --cached | sed /^index/d >diff &&
261 test_cmp expected diff &&
262 test_cmp expected-output output
265 test_expect_success 'setup expected' '
266 cat >expected <<-\EOF
267 diff --git a/non-empty b/non-empty
268 deleted file mode 100644
276 test_expect_success 'deleting a non-empty file' '
278 echo content >non-empty &&
280 git commit -m non-empty &&
282 echo y | git add -p non-empty &&
283 git diff --cached | sed /^index/d >diff &&
284 test_cmp expected diff
287 test_expect_success 'setup expected' '
288 cat >expected <<-\EOF
289 diff --git a/empty b/empty
290 deleted file mode 100644
294 test_expect_success 'deleting an empty file' '
298 git commit -m empty &&
300 echo y | git add -p empty &&
301 git diff --cached | sed /^index/d >diff &&
302 test_cmp expected diff
305 test_expect_success 'split hunk setup' '
307 test_write_lines 10 20 30 40 50 60 >test &&
310 git commit -m test &&
312 test_write_lines 10 15 20 21 22 23 24 30 40 50 60 >test
315 test_expect_success 'split hunk "add -p (edit)"' '
316 # Split, say Edit and do nothing. Then:
318 # 1. Broken version results in a patch that does not apply and
319 # only takes [y/n] (edit again) so the first q is discarded
320 # and then n attempts to discard the edit. Repeat q enough
323 # 2. Correct version applies the (not)edited version, and asks
324 # about the next hunk, against which we say q and program
326 printf "%s\n" s e q n q q |
327 EDITOR=: git add -p &&
328 git diff | sed /^index/d >actual &&
332 test_expect_failure 'split hunk "add -p (no, yes, edit)"' '
333 test_write_lines 5 10 20 21 30 31 40 50 60 >test &&
335 # test sequence is s(plit), n(o), y(es), e(dit)
336 # q n q q is there to make sure we exit at the end.
337 printf "%s\n" s n y e q n q q |
338 EDITOR=: git add -p 2>error &&
339 test_must_be_empty error &&
340 git diff | sed /^index/d >actual &&
344 test_expect_success 'patch mode ignores unmerged entries' '
346 test_commit conflict &&
347 test_commit non-conflict &&
348 git checkout -b side &&
349 test_commit side conflict.t &&
350 git checkout master &&
351 test_commit master conflict.t &&
352 test_must_fail git merge side &&
353 echo changed >non-conflict.t &&
354 echo y | git add -p >output &&
355 ! grep a/conflict.t output &&
356 cat >expected <<-\EOF &&
357 * Unmerged path conflict.t
358 diff --git a/non-conflict.t b/non-conflict.t
365 git diff --cached | sed /^index/d >diff &&
366 test_cmp expected diff
369 test_expect_success TTY 'diffs can be colorized' '
372 echo content >test &&
373 printf y | test_terminal git add -p >output 2>&1 &&
375 # We do not want to depend on the exact coloring scheme
376 # git uses for diffs, so just check that we saw some kind of color.
377 grep "$(printf "\\033")" output
380 test_expect_success 'patch-mode via -i prompts for files' '
385 git add -i <<-\EOF &&
394 git diff --cached --name-only >actual &&
395 test_cmp expect actual
398 test_expect_success 'add -p handles globs' '
403 echo base >subdir/two.c &&
405 git commit -m base &&
407 echo change >one.c &&
408 echo change >subdir/two.c &&
409 git add -p "*.c" <<-\EOF &&
414 cat >expect <<-\EOF &&
418 git diff --cached --name-only >actual &&
419 test_cmp expect actual
422 test_expect_success 'add -p handles relative paths' '
425 echo base >relpath.c &&
427 git commit -m relpath &&
429 echo change >relpath.c &&
431 git -C subdir add -p .. 2>error <<-\EOF &&
435 test_must_be_empty error &&
437 cat >expect <<-\EOF &&
440 git diff --cached --name-only >actual &&
441 test_cmp expect actual
444 test_expect_success 'add -p does not expand argument lists' '
447 echo content >not-changed &&
448 git add not-changed &&
449 git commit -m "add not-changed file" &&
452 GIT_TRACE=$(pwd)/trace.out git add -p . <<-\EOF &&
456 # we know that "file" must be mentioned since we actually
457 # update it, but we want to be sure that our "." pathspec
458 # was not expanded into the argument list of any command.
459 # So look only for "not-changed".
460 ! grep not-changed trace.out
463 test_expect_success 'hunk-editing handles custom comment char' '
465 echo change >>file &&
466 test_config core.commentChar "\$" &&
467 echo e | GIT_EDITOR=true git add -p &&
471 test_expect_success 'add -p works even with color.ui=always' '
473 echo change >>file &&
474 test_config color.ui always &&
475 echo y | git add -p &&
477 git diff --cached --name-only >actual &&
478 test_cmp expect actual
481 test_expect_success 'setup different kinds of dirty submodules' '
482 test_create_repo for-submodules &&
485 test_commit initial &&
486 test_create_repo dirty-head &&
491 cp -R dirty-head dirty-otherwise &&
492 cp -R dirty-head dirty-both-ways &&
493 git add dirty-head &&
494 git add dirty-otherwise dirty-both-ways &&
495 git commit -m initial &&
498 test_commit updated &&
499 cd ../dirty-both-ways &&
500 test_commit updated &&
501 echo dirty >>initial &&
503 cd ../dirty-otherwise &&
504 echo dirty >>initial &&
507 git -C for-submodules diff-files --name-only >actual &&
508 cat >expected <<-\EOF &&
513 test_cmp expected actual &&
514 git -C for-submodules diff-files --name-only --ignore-submodules=dirty >actual &&
515 cat >expected <<-\EOF &&
519 test_cmp expected actual
522 test_expect_success 'status ignores dirty submodules (except HEAD)' '
523 git -C for-submodules add -i </dev/null >output &&
524 grep dirty-head output &&
525 grep dirty-both-ways output &&
526 ! grep dirty-otherwise output
529 test_expect_success 'set up pathological context' '
531 test_write_lines a a a a a a a a a a a >a &&
534 test_write_lines c b a a a a a a a b a a a a >a &&
535 test_write_lines a a a a a a a b a a a a >expected-1 &&
536 test_write_lines b a a a a a a a b a a a a >expected-2 &&
537 # check editing can cope with missing header and deleted context lines
538 # as well as changes to other lines
539 test_write_lines +b " a" >patch
542 test_expect_success 'add -p works with pathological context lines' '
546 git cat-file blob :a >actual &&
547 test_cmp expected-1 actual
550 test_expect_success 'add -p patch editing works with pathological context lines' '
552 test_set_editor "$FAKE_EDITOR" &&
553 # n q q below is in case edit fails
554 printf "%s\n" e y n q q |
556 git cat-file blob :a >actual &&
557 test_cmp expected-2 actual