Merge branch 'jk/log-cherry-pick-duplicate-patches' into maint
[git] / t / t2016-checkout-patch.sh
1 #!/bin/sh
2
3 test_description='git checkout --patch'
4
5 . ./lib-patch-mode.sh
6
7 test_expect_success PERL 'setup' '
8         mkdir dir &&
9         echo parent > dir/foo &&
10         echo dummy > bar &&
11         git add bar dir/foo &&
12         git commit -m initial &&
13         test_tick &&
14         test_commit second dir/foo head &&
15         set_and_save_state bar bar_work bar_index &&
16         save_head
17 '
18
19 # note: bar sorts before dir/foo, so the first 'n' is always to skip 'bar'
20
21 # NEEDSWORK: Since the builtin add-p is used when $GIT_TEST_ADD_I_USE_BUILTIN
22 # is given, we should replace the PERL prerequisite with an ADD_I prerequisite
23 # which first checks if $GIT_TEST_ADD_I_USE_BUILTIN is defined before checking
24 # PERL.
25 test_expect_success PERL 'saying "n" does nothing' '
26         set_and_save_state dir/foo work head &&
27         test_write_lines n n | git checkout -p &&
28         verify_saved_state bar &&
29         verify_saved_state dir/foo
30 '
31
32 test_expect_success PERL 'git checkout -p' '
33         test_write_lines n y | git checkout -p &&
34         verify_saved_state bar &&
35         verify_state dir/foo head head
36 '
37
38 test_expect_success PERL 'git checkout -p with staged changes' '
39         set_state dir/foo work index &&
40         test_write_lines n y | git checkout -p &&
41         verify_saved_state bar &&
42         verify_state dir/foo index index
43 '
44
45 test_expect_success PERL 'git checkout -p HEAD with NO staged changes: abort' '
46         set_and_save_state dir/foo work head &&
47         test_write_lines n y n | git checkout -p HEAD &&
48         verify_saved_state bar &&
49         verify_saved_state dir/foo
50 '
51
52 test_expect_success PERL 'git checkout -p HEAD with NO staged changes: apply' '
53         test_write_lines n y y | git checkout -p HEAD &&
54         verify_saved_state bar &&
55         verify_state dir/foo head head
56 '
57
58 test_expect_success PERL 'git checkout -p HEAD with change already staged' '
59         set_state dir/foo index index &&
60         # the third n is to get out in case it mistakenly does not apply
61         test_write_lines n y n | git checkout -p HEAD &&
62         verify_saved_state bar &&
63         verify_state dir/foo head head
64 '
65
66 test_expect_success PERL 'git checkout -p HEAD^...' '
67         # the third n is to get out in case it mistakenly does not apply
68         test_write_lines n y n | git checkout -p HEAD^... &&
69         verify_saved_state bar &&
70         verify_state dir/foo parent parent
71 '
72
73 test_expect_success PERL 'git checkout -p HEAD^' '
74         # the third n is to get out in case it mistakenly does not apply
75         test_write_lines n y n | git checkout -p HEAD^ &&
76         verify_saved_state bar &&
77         verify_state dir/foo parent parent
78 '
79
80 test_expect_success PERL 'git checkout -p handles deletion' '
81         set_state dir/foo work index &&
82         rm dir/foo &&
83         test_write_lines n y | git checkout -p &&
84         verify_saved_state bar &&
85         verify_state dir/foo index index
86 '
87
88 # The idea in the rest is that bar sorts first, so we always say 'y'
89 # first and if the path limiter fails it'll apply to bar instead of
90 # dir/foo.  There's always an extra 'n' to reject edits to dir/foo in
91 # the failure case (and thus get out of the loop).
92
93 test_expect_success PERL 'path limiting works: dir' '
94         set_state dir/foo work head &&
95         test_write_lines y n | git checkout -p dir &&
96         verify_saved_state bar &&
97         verify_state dir/foo head head
98 '
99
100 test_expect_success PERL 'path limiting works: -- dir' '
101         set_state dir/foo work head &&
102         test_write_lines y n | git checkout -p -- dir &&
103         verify_saved_state bar &&
104         verify_state dir/foo head head
105 '
106
107 test_expect_success PERL 'path limiting works: HEAD^ -- dir' '
108         # the third n is to get out in case it mistakenly does not apply
109         test_write_lines y n n | git checkout -p HEAD^ -- dir &&
110         verify_saved_state bar &&
111         verify_state dir/foo parent parent
112 '
113
114 test_expect_success PERL 'path limiting works: foo inside dir' '
115         set_state dir/foo work head &&
116         # the third n is to get out in case it mistakenly does not apply
117         test_write_lines y n n | (cd dir && git checkout -p foo) &&
118         verify_saved_state bar &&
119         verify_state dir/foo head head
120 '
121
122 test_expect_success PERL 'none of this moved HEAD' '
123         verify_saved_head
124 '
125
126 test_expect_success PERL 'empty tree can be handled' '
127         test_when_finished "git reset --hard" &&
128         git checkout -p $(test_oid empty_tree) --
129 '
130
131 test_done