]>
Commit | Line | Data |
---|---|---|
39ac7a7d TRC |
1 | #!/bin/sh |
2 | ||
f1842ff5 | 3 | test_description='checkout' |
39ac7a7d TRC |
4 | |
5 | . ./test-lib.sh | |
6 | ||
4a6f11fd | 7 | # Arguments: [!] <branch> <oid> [<checkout options>] |
39ac7a7d TRC |
8 | # |
9 | # Runs "git checkout" to switch to <branch>, testing that | |
10 | # | |
11 | # 1) we are on the specified branch, <branch>; | |
4a6f11fd | 12 | # 2) HEAD is <oid>; if <oid> is not specified, the old HEAD is used. |
39ac7a7d TRC |
13 | # |
14 | # If <checkout options> is not specified, "git checkout" is run with -b. | |
30c03676 DL |
15 | # |
16 | # If the first argument is `!`, "git checkout" is expected to fail when | |
17 | # it is run. | |
7ffb5461 | 18 | do_checkout () { |
30c03676 DL |
19 | should_fail= && |
20 | if test "x$1" = "x!" | |
21 | then | |
22 | should_fail=yes && | |
23 | shift | |
24 | fi && | |
39ac7a7d TRC |
25 | exp_branch=$1 && |
26 | exp_ref="refs/heads/$exp_branch" && | |
27 | ||
4a6f11fd DL |
28 | # if <oid> is not specified, use HEAD. |
29 | exp_oid=${2:-$(git rev-parse --verify HEAD)} && | |
39ac7a7d TRC |
30 | |
31 | # default options for git checkout: -b | |
5020f680 DL |
32 | if test -z "$3" |
33 | then | |
39ac7a7d TRC |
34 | opts="-b" |
35 | else | |
36 | opts="$3" | |
37 | fi | |
38 | ||
30c03676 DL |
39 | if test -n "$should_fail" |
40 | then | |
4a6f11fd | 41 | test_must_fail git checkout $opts $exp_branch $exp_oid |
30c03676 | 42 | else |
4a6f11fd | 43 | git checkout $opts $exp_branch $exp_oid && |
62e80fcb DL |
44 | echo "$exp_ref" >ref.expect && |
45 | git rev-parse --symbolic-full-name HEAD >ref.actual && | |
46 | test_cmp ref.expect ref.actual && | |
4a6f11fd DL |
47 | echo "$exp_oid" >oid.expect && |
48 | git rev-parse --verify HEAD >oid.actual && | |
49 | test_cmp oid.expect oid.actual | |
30c03676 | 50 | fi |
39ac7a7d TRC |
51 | } |
52 | ||
7ffb5461 | 53 | test_dirty_unmergeable () { |
40caa536 DL |
54 | test_expect_code 1 git diff --exit-code |
55 | } | |
56 | ||
57 | test_dirty_unmergeable_discards_changes () { | |
58 | git diff --exit-code | |
39ac7a7d TRC |
59 | } |
60 | ||
7ffb5461 | 61 | setup_dirty_unmergeable () { |
39ac7a7d TRC |
62 | echo >>file1 change2 |
63 | } | |
64 | ||
7ffb5461 | 65 | test_dirty_mergeable () { |
40caa536 DL |
66 | test_expect_code 1 git diff --cached --exit-code |
67 | } | |
68 | ||
69 | test_dirty_mergeable_discards_changes () { | |
70 | git diff --cached --exit-code | |
39ac7a7d TRC |
71 | } |
72 | ||
7ffb5461 | 73 | setup_dirty_mergeable () { |
39ac7a7d TRC |
74 | echo >file2 file2 && |
75 | git add file2 | |
76 | } | |
77 | ||
78 | test_expect_success 'setup' ' | |
79 | test_commit initial file1 && | |
80 | HEAD1=$(git rev-parse --verify HEAD) && | |
81 | ||
82 | test_commit change1 file1 && | |
83 | HEAD2=$(git rev-parse --verify HEAD) && | |
84 | ||
85 | git branch -m branch1 | |
86 | ' | |
87 | ||
88 | test_expect_success 'checkout -b to a new branch, set to HEAD' ' | |
27434bf0 DL |
89 | test_when_finished " |
90 | git checkout branch1 && | |
91 | test_might_fail git branch -D branch2" && | |
39ac7a7d TRC |
92 | do_checkout branch2 |
93 | ' | |
94 | ||
e3d6539d DL |
95 | test_expect_success 'checkout -b to a merge base' ' |
96 | test_when_finished " | |
97 | git checkout branch1 && | |
98 | test_might_fail git branch -D branch2" && | |
99 | git checkout -b branch2 branch1... | |
100 | ' | |
101 | ||
39ac7a7d | 102 | test_expect_success 'checkout -b to a new branch, set to an explicit ref' ' |
27434bf0 DL |
103 | test_when_finished " |
104 | git checkout branch1 && | |
105 | test_might_fail git branch -D branch2" && | |
39ac7a7d TRC |
106 | do_checkout branch2 $HEAD1 |
107 | ' | |
108 | ||
109 | test_expect_success 'checkout -b to a new branch with unmergeable changes fails' ' | |
39ac7a7d | 110 | setup_dirty_unmergeable && |
30c03676 | 111 | do_checkout ! branch2 $HEAD1 && |
39ac7a7d TRC |
112 | test_dirty_unmergeable |
113 | ' | |
114 | ||
115 | test_expect_success 'checkout -f -b to a new branch with unmergeable changes discards changes' ' | |
27434bf0 DL |
116 | test_when_finished " |
117 | git checkout branch1 && | |
118 | test_might_fail git branch -D branch2" && | |
119 | ||
39ac7a7d TRC |
120 | # still dirty and on branch1 |
121 | do_checkout branch2 $HEAD1 "-f -b" && | |
40caa536 | 122 | test_dirty_unmergeable_discards_changes |
39ac7a7d TRC |
123 | ' |
124 | ||
125 | test_expect_success 'checkout -b to a new branch preserves mergeable changes' ' | |
27434bf0 DL |
126 | test_when_finished " |
127 | git reset --hard && | |
128 | git checkout branch1 && | |
129 | test_might_fail git branch -D branch2" && | |
39ac7a7d TRC |
130 | |
131 | setup_dirty_mergeable && | |
132 | do_checkout branch2 $HEAD1 && | |
133 | test_dirty_mergeable | |
134 | ' | |
135 | ||
136 | test_expect_success 'checkout -f -b to a new branch with mergeable changes discards changes' ' | |
27434bf0 | 137 | test_when_finished git reset --hard HEAD && |
39ac7a7d TRC |
138 | setup_dirty_mergeable && |
139 | do_checkout branch2 $HEAD1 "-f -b" && | |
40caa536 | 140 | test_dirty_mergeable_discards_changes |
39ac7a7d TRC |
141 | ' |
142 | ||
143 | test_expect_success 'checkout -b to an existing branch fails' ' | |
27434bf0 | 144 | test_when_finished git reset --hard HEAD && |
30c03676 | 145 | do_checkout ! branch2 $HEAD2 |
39ac7a7d TRC |
146 | ' |
147 | ||
587a9ee7 | 148 | test_expect_success 'checkout -b to @{-1} fails with the right branch name' ' |
587a9ee7 CI |
149 | git checkout branch1 && |
150 | git checkout branch2 && | |
151 | echo >expect "fatal: A branch named '\''branch1'\'' already exists." && | |
152 | test_must_fail git checkout -b @{-1} 2>actual && | |
1108cea7 | 153 | test_cmp expect actual |
587a9ee7 CI |
154 | ' |
155 | ||
02ac9837 TRC |
156 | test_expect_success 'checkout -B to an existing branch resets branch to HEAD' ' |
157 | git checkout branch1 && | |
158 | ||
159 | do_checkout branch2 "" -B | |
160 | ' | |
161 | ||
e3d6539d DL |
162 | test_expect_success 'checkout -B to a merge base' ' |
163 | git checkout branch1 && | |
164 | ||
165 | git checkout -B branch2 branch1... | |
166 | ' | |
167 | ||
cc701483 | 168 | test_expect_success 'checkout -B to an existing branch from detached HEAD resets branch to HEAD' ' |
62e80fcb DL |
169 | head=$(git rev-parse --verify HEAD) && |
170 | git checkout "$head" && | |
cc701483 TRC |
171 | |
172 | do_checkout branch2 "" -B | |
173 | ' | |
174 | ||
02ac9837 TRC |
175 | test_expect_success 'checkout -B to an existing branch with an explicit ref resets branch to that ref' ' |
176 | git checkout branch1 && | |
177 | ||
178 | do_checkout branch2 $HEAD1 -B | |
179 | ' | |
180 | ||
181 | test_expect_success 'checkout -B to an existing branch with unmergeable changes fails' ' | |
182 | git checkout branch1 && | |
183 | ||
184 | setup_dirty_unmergeable && | |
30c03676 | 185 | do_checkout ! branch2 $HEAD1 -B && |
02ac9837 TRC |
186 | test_dirty_unmergeable |
187 | ' | |
188 | ||
189 | test_expect_success 'checkout -f -B to an existing branch with unmergeable changes discards changes' ' | |
190 | # still dirty and on branch1 | |
191 | do_checkout branch2 $HEAD1 "-f -B" && | |
40caa536 | 192 | test_dirty_unmergeable_discards_changes |
02ac9837 TRC |
193 | ' |
194 | ||
195 | test_expect_success 'checkout -B to an existing branch preserves mergeable changes' ' | |
27434bf0 | 196 | test_when_finished git reset --hard && |
02ac9837 TRC |
197 | git checkout branch1 && |
198 | ||
199 | setup_dirty_mergeable && | |
200 | do_checkout branch2 $HEAD1 -B && | |
201 | test_dirty_mergeable | |
202 | ' | |
203 | ||
204 | test_expect_success 'checkout -f -B to an existing branch with mergeable changes discards changes' ' | |
02ac9837 TRC |
205 | git checkout branch1 && |
206 | ||
207 | setup_dirty_mergeable && | |
208 | do_checkout branch2 $HEAD1 "-f -B" && | |
40caa536 | 209 | test_dirty_mergeable_discards_changes |
02ac9837 TRC |
210 | ' |
211 | ||
c17b2294 JH |
212 | test_expect_success 'checkout -b <describe>' ' |
213 | git tag -f -m "First commit" initial initial && | |
214 | git checkout -f change1 && | |
215 | name=$(git describe) && | |
216 | git checkout -b $name && | |
217 | git diff --exit-code change1 && | |
218 | echo "refs/heads/$name" >expect && | |
219 | git symbolic-ref HEAD >actual && | |
220 | test_cmp expect actual | |
221 | ' | |
222 | ||
39bd6f72 | 223 | test_expect_success 'checkout -B to the current branch works' ' |
55c4a673 | 224 | git checkout branch1 && |
39bd6f72 JN |
225 | git checkout -B branch1-scratch && |
226 | ||
55c4a673 | 227 | setup_dirty_mergeable && |
39bd6f72 JN |
228 | git checkout -B branch1-scratch initial && |
229 | test_dirty_mergeable | |
55c4a673 CI |
230 | ' |
231 | ||
8424bfd4 | 232 | test_expect_success 'checkout -b after clone --no-checkout does a checkout of HEAD' ' |
91e3d7ca BP |
233 | git init src && |
234 | test_commit -C src a && | |
235 | rev="$(git -C src rev-parse HEAD)" && | |
236 | git clone --no-checkout src dest && | |
237 | git -C dest checkout "$rev" -b branch && | |
238 | test_path_is_file dest/a.t | |
239 | ' | |
240 | ||
681c637b EN |
241 | test_expect_success 'checkout -b to a new branch preserves mergeable changes despite sparse-checkout' ' |
242 | test_when_finished " | |
243 | git reset --hard && | |
244 | git checkout branch1-scratch && | |
245 | test_might_fail git branch -D branch3 && | |
246 | git config core.sparseCheckout false && | |
247 | rm .git/info/sparse-checkout" && | |
248 | ||
249 | test_commit file2 && | |
250 | ||
251 | echo stuff >>file1 && | |
252 | echo file2 >.git/info/sparse-checkout && | |
253 | git config core.sparseCheckout true && | |
254 | ||
255 | CURHEAD=$(git rev-parse HEAD) && | |
256 | do_checkout branch3 $CURHEAD && | |
257 | ||
258 | echo file1 >expect && | |
259 | git diff --name-only >actual && | |
260 | test_cmp expect actual | |
261 | ' | |
262 | ||
16ab794b RS |
263 | test_expect_success 'checkout -b rejects an invalid start point' ' |
264 | test_must_fail git checkout -b branch4 file1 2>err && | |
265 | test_i18ngrep "is not a commit" err | |
266 | ' | |
267 | ||
bb2198fb | 268 | test_expect_success 'checkout -b rejects an extra path argument' ' |
16ab794b RS |
269 | test_must_fail git checkout -b branch5 branch1 file1 2>err && |
270 | test_i18ngrep "Cannot update paths and switch to branch" err | |
271 | ' | |
272 | ||
39ac7a7d | 273 | test_done |