3 test_description
='git checkout --patch'
5 TEST_PASSES_SANITIZE_LEAK
=true
8 test_expect_success
'setup' '
10 echo parent > dir/foo &&
12 git add bar dir/foo &&
13 git commit -m initial &&
15 test_commit second dir/foo head &&
16 set_and_save_state bar bar_work bar_index &&
20 # note: bar sorts before dir/foo, so the first 'n' is always to skip 'bar'
22 test_expect_success
'saying "n" does nothing' '
23 set_and_save_state dir/foo work head &&
24 test_write_lines n n | git checkout -p &&
25 verify_saved_state bar &&
26 verify_saved_state dir/foo
29 test_expect_success
'git checkout -p' '
30 test_write_lines n y | git checkout -p &&
31 verify_saved_state bar &&
32 verify_state dir/foo head head
35 test_expect_success
'git checkout -p with staged changes' '
36 set_state dir/foo work index &&
37 test_write_lines n y | git checkout -p &&
38 verify_saved_state bar &&
39 verify_state dir/foo index index
44 test_expect_success
"git checkout -p $opt with NO staged changes: abort" '
45 set_and_save_state dir/foo work head &&
46 test_write_lines n y n | git checkout -p $opt >output &&
47 verify_saved_state bar &&
48 verify_saved_state dir/foo &&
49 test_grep "Discard" output
52 test_expect_success
"git checkout -p $opt with NO staged changes: apply" '
53 test_write_lines n y y | git checkout -p $opt >output &&
54 verify_saved_state bar &&
55 verify_state dir/foo head head &&
56 test_grep "Discard" output
59 test_expect_success
"git checkout -p $opt with change already staged" '
60 set_state dir/foo index index &&
61 # the third n is to get out in case it mistakenly does not apply
62 test_write_lines n y n | git checkout -p $opt >output &&
63 verify_saved_state bar &&
64 verify_state dir/foo head head &&
65 test_grep "Discard" output
69 test_expect_success
'git checkout -p HEAD^...' '
70 # the third n is to get out in case it mistakenly does not apply
71 test_write_lines n y n | git checkout -p HEAD^... &&
72 verify_saved_state bar &&
73 verify_state dir/foo parent parent
76 test_expect_success
'git checkout -p HEAD^' '
77 # the third n is to get out in case it mistakenly does not apply
78 test_write_lines n y n | git checkout -p HEAD^ &&
79 verify_saved_state bar &&
80 verify_state dir/foo parent parent
83 test_expect_success
'git checkout -p handles deletion' '
84 set_state dir/foo work index &&
86 test_write_lines n y | git checkout -p &&
87 verify_saved_state bar &&
88 verify_state dir/foo index index
91 # The idea in the rest is that bar sorts first, so we always say 'y'
92 # first and if the path limiter fails it'll apply to bar instead of
93 # dir/foo. There's always an extra 'n' to reject edits to dir/foo in
94 # the failure case (and thus get out of the loop).
96 test_expect_success
'path limiting works: dir' '
97 set_state dir/foo work head &&
98 test_write_lines y n | git checkout -p dir &&
99 verify_saved_state bar &&
100 verify_state dir/foo head head
103 test_expect_success
'path limiting works: -- dir' '
104 set_state dir/foo work head &&
105 test_write_lines y n | git checkout -p -- dir &&
106 verify_saved_state bar &&
107 verify_state dir/foo head head
110 test_expect_success
'path limiting works: HEAD^ -- dir' '
111 # the third n is to get out in case it mistakenly does not apply
112 test_write_lines y n n | git checkout -p HEAD^ -- dir &&
113 verify_saved_state bar &&
114 verify_state dir/foo parent parent
117 test_expect_success
'path limiting works: foo inside dir' '
118 set_state dir/foo work head &&
119 # the third n is to get out in case it mistakenly does not apply
120 test_write_lines y n n | (cd dir && git checkout -p foo) &&
121 verify_saved_state bar &&
122 verify_state dir/foo head head
125 test_expect_success
'none of this moved HEAD' '
129 test_expect_success
'empty tree can be handled' '
130 test_when_finished "git reset --hard" &&
131 git checkout -p $(test_oid empty_tree) --