]> git.ipfire.org Git - thirdparty/git.git/blame - t/t2024-checkout-dwim.sh
The third batch
[thirdparty/git.git] / t / t2024-checkout-dwim.sh
CommitLineData
399e4a1c
JH
1#!/bin/sh
2
3test_description='checkout <branch>
4
5Ensures that checkout on an unborn branch does what the user expects'
6
7. ./test-lib.sh
8
9# Is the current branch "refs/heads/$1"?
10test_branch () {
11 printf "%s\n" "refs/heads/$1" >expect.HEAD &&
12 git symbolic-ref HEAD >actual.HEAD &&
13 test_cmp expect.HEAD actual.HEAD
14}
15
16# Is branch "refs/heads/$1" set to pull from "$2/$3"?
17test_branch_upstream () {
18 printf "%s\n" "$2" "refs/heads/$3" >expect.upstream &&
19 {
20 git config "branch.$1.remote" &&
21 git config "branch.$1.merge"
22 } >actual.upstream &&
23 test_cmp expect.upstream actual.upstream
24}
25
c8cbf20c 26status_uno_is_clean () {
c8cbf20c 27 git status -uno --porcelain >status.actual &&
9f4bcf81 28 test_must_be_empty status.actual
c8cbf20c
ÆAB
29}
30
399e4a1c 31test_expect_success 'setup' '
883b98ef 32 test_commit my_main &&
399e4a1c
JH
33 git init repo_a &&
34 (
35 cd repo_a &&
883b98ef 36 test_commit a_main &&
399e4a1c
JH
37 git checkout -b foo &&
38 test_commit a_foo &&
39 git checkout -b bar &&
fa74180d
AM
40 test_commit a_bar &&
41 git checkout -b ambiguous_branch_and_file &&
42 test_commit a_ambiguous_branch_and_file
399e4a1c
JH
43 ) &&
44 git init repo_b &&
45 (
46 cd repo_b &&
883b98ef 47 test_commit b_main &&
399e4a1c
JH
48 git checkout -b foo &&
49 test_commit b_foo &&
50 git checkout -b baz &&
fa74180d
AM
51 test_commit b_baz &&
52 git checkout -b ambiguous_branch_and_file &&
53 test_commit b_ambiguous_branch_and_file
399e4a1c
JH
54 ) &&
55 git remote add repo_a repo_a &&
56 git remote add repo_b repo_b &&
57 git config remote.repo_b.fetch \
58 "+refs/heads/*:refs/remotes/other_b/*" &&
59 git fetch --all
60'
61
62test_expect_success 'checkout of non-existing branch fails' '
883b98ef 63 git checkout -B main &&
399e4a1c
JH
64 test_might_fail git branch -D xyzzy &&
65
66 test_must_fail git checkout xyzzy &&
c8cbf20c 67 status_uno_is_clean &&
399e4a1c 68 test_must_fail git rev-parse --verify refs/heads/xyzzy &&
883b98ef 69 test_branch main
399e4a1c
JH
70'
71
ec2764ee 72test_expect_success 'checkout of branch from multiple remotes fails #1' '
883b98ef 73 git checkout -B main &&
399e4a1c
JH
74 test_might_fail git branch -D foo &&
75
76 test_must_fail git checkout foo &&
c8cbf20c 77 status_uno_is_clean &&
399e4a1c 78 test_must_fail git rev-parse --verify refs/heads/foo &&
883b98ef 79 test_branch main
399e4a1c
JH
80'
81
fa74180d
AM
82test_expect_success 'when arg matches multiple remotes, do not fallback to interpreting as pathspec' '
83 # create a file with name matching remote branch name
84 git checkout -b t_ambiguous_branch_and_file &&
85 >ambiguous_branch_and_file &&
86 git add ambiguous_branch_and_file &&
87 git commit -m "ambiguous_branch_and_file" &&
88
89 # modify file to verify that it will not be touched by checkout
90 test_when_finished "git checkout -- ambiguous_branch_and_file" &&
91 echo "file contents" >ambiguous_branch_and_file &&
92 cp ambiguous_branch_and_file expect &&
93
94 test_must_fail git checkout ambiguous_branch_and_file 2>err &&
95
6789275d 96 test_grep "matched multiple (2) remote tracking branches" err &&
fa74180d
AM
97
98 # file must not be altered
99 test_cmp expect ambiguous_branch_and_file
100'
101
ad8d5104 102test_expect_success 'checkout of branch from multiple remotes fails with advice' '
883b98ef 103 git checkout -B main &&
ad8d5104
ÆAB
104 test_might_fail git branch -D foo &&
105 test_must_fail git checkout foo 2>stderr &&
883b98ef 106 test_branch main &&
ad8d5104 107 status_uno_is_clean &&
6789275d 108 test_grep "^hint: " stderr &&
ad8d5104
ÆAB
109 test_must_fail git -c advice.checkoutAmbiguousRemoteBranchName=false \
110 checkout foo 2>stderr &&
883b98ef 111 test_branch main &&
ad8d5104 112 status_uno_is_clean &&
6789275d 113 test_grep ! "^hint: " stderr
3338e995
ÆAB
114'
115
7abc1869 116test_expect_success 'checkout -p with multiple remotes does not print advice' '
883b98ef 117 git checkout -B main &&
3338e995
ÆAB
118 test_might_fail git branch -D foo &&
119
8d7b558b 120 git checkout -p foo 2>stderr &&
6789275d 121 test_grep ! "^hint: " stderr &&
8d7b558b
ÆAB
122 status_uno_is_clean
123'
124
125test_expect_success 'checkout of branch from multiple remotes succeeds with checkout.defaultRemote #1' '
883b98ef 126 git checkout -B main &&
8d7b558b
ÆAB
127 status_uno_is_clean &&
128 test_might_fail git branch -D foo &&
129
130 git -c checkout.defaultRemote=repo_a checkout foo &&
131 status_uno_is_clean &&
132 test_branch foo &&
133 test_cmp_rev remotes/repo_a/foo HEAD &&
134 test_branch_upstream foo repo_a foo
ad8d5104
ÆAB
135'
136
399e4a1c 137test_expect_success 'checkout of branch from a single remote succeeds #1' '
883b98ef 138 git checkout -B main &&
399e4a1c
JH
139 test_might_fail git branch -D bar &&
140
141 git checkout bar &&
c8cbf20c 142 status_uno_is_clean &&
399e4a1c
JH
143 test_branch bar &&
144 test_cmp_rev remotes/repo_a/bar HEAD &&
145 test_branch_upstream bar repo_a bar
146'
147
148test_expect_success 'checkout of branch from a single remote succeeds #2' '
883b98ef 149 git checkout -B main &&
399e4a1c
JH
150 test_might_fail git branch -D baz &&
151
152 git checkout baz &&
c8cbf20c 153 status_uno_is_clean &&
399e4a1c
JH
154 test_branch baz &&
155 test_cmp_rev remotes/other_b/baz HEAD &&
156 test_branch_upstream baz repo_b baz
157'
158
159test_expect_success '--no-guess suppresses branch auto-vivification' '
883b98ef 160 git checkout -B main &&
c8cbf20c 161 status_uno_is_clean &&
399e4a1c
JH
162 test_might_fail git branch -D bar &&
163
164 test_must_fail git checkout --no-guess bar &&
165 test_must_fail git rev-parse --verify refs/heads/bar &&
883b98ef 166 test_branch main
399e4a1c
JH
167'
168
64f1f58f 169test_expect_success 'checkout.guess = false suppresses branch auto-vivification' '
883b98ef 170 git checkout -B main &&
64f1f58f
DL
171 status_uno_is_clean &&
172 test_might_fail git branch -D bar &&
173
174 test_config checkout.guess false &&
175 test_must_fail git checkout bar &&
176 test_must_fail git rev-parse --verify refs/heads/bar &&
883b98ef 177 test_branch main
64f1f58f
DL
178'
179
ec2764ee 180test_expect_success 'setup more remotes with unconventional refspecs' '
883b98ef 181 git checkout -B main &&
c8cbf20c 182 status_uno_is_clean &&
ec2764ee
JH
183 git init repo_c &&
184 (
185 cd repo_c &&
883b98ef 186 test_commit c_main &&
ec2764ee 187 git checkout -b bar &&
5a517b1c 188 test_commit c_bar &&
ec2764ee
JH
189 git checkout -b spam &&
190 test_commit c_spam
191 ) &&
192 git init repo_d &&
193 (
194 cd repo_d &&
883b98ef 195 test_commit d_main &&
ec2764ee 196 git checkout -b baz &&
5a517b1c 197 test_commit d_baz &&
ec2764ee 198 git checkout -b eggs &&
5a517b1c 199 test_commit d_eggs
ec2764ee
JH
200 ) &&
201 git remote add repo_c repo_c &&
202 git config remote.repo_c.fetch \
203 "+refs/heads/*:refs/remotes/extra_dir/repo_c/extra_dir/*" &&
204 git remote add repo_d repo_d &&
205 git config remote.repo_d.fetch \
206 "+refs/heads/*:refs/repo_d/*" &&
207 git fetch --all
208'
209
fa83a33b 210test_expect_success 'checkout of branch from multiple remotes fails #2' '
883b98ef 211 git checkout -B main &&
c8cbf20c 212 status_uno_is_clean &&
ec2764ee
JH
213 test_might_fail git branch -D bar &&
214
215 test_must_fail git checkout bar &&
c8cbf20c 216 status_uno_is_clean &&
ec2764ee 217 test_must_fail git rev-parse --verify refs/heads/bar &&
883b98ef 218 test_branch main
ec2764ee
JH
219'
220
fa83a33b 221test_expect_success 'checkout of branch from multiple remotes fails #3' '
883b98ef 222 git checkout -B main &&
c8cbf20c 223 status_uno_is_clean &&
ec2764ee
JH
224 test_might_fail git branch -D baz &&
225
226 test_must_fail git checkout baz &&
c8cbf20c 227 status_uno_is_clean &&
ec2764ee 228 test_must_fail git rev-parse --verify refs/heads/baz &&
883b98ef 229 test_branch main
ec2764ee
JH
230'
231
fa83a33b 232test_expect_success 'checkout of branch from a single remote succeeds #3' '
883b98ef 233 git checkout -B main &&
c8cbf20c 234 status_uno_is_clean &&
ec2764ee
JH
235 test_might_fail git branch -D spam &&
236
237 git checkout spam &&
c8cbf20c 238 status_uno_is_clean &&
ec2764ee
JH
239 test_branch spam &&
240 test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD &&
241 test_branch_upstream spam repo_c spam
242'
243
41c21f22 244test_expect_success 'checkout of branch from a single remote succeeds #4' '
883b98ef 245 git checkout -B main &&
c8cbf20c 246 status_uno_is_clean &&
ec2764ee
JH
247 test_might_fail git branch -D eggs &&
248
249 git checkout eggs &&
c8cbf20c 250 status_uno_is_clean &&
ec2764ee
JH
251 test_branch eggs &&
252 test_cmp_rev refs/repo_d/eggs HEAD &&
253 test_branch_upstream eggs repo_d eggs
254'
255
a047fafc 256test_expect_success 'checkout of branch with a file having the same name fails' '
883b98ef 257 git checkout -B main &&
c8cbf20c 258 status_uno_is_clean &&
a047fafc
MM
259 test_might_fail git branch -D spam &&
260
261 >spam &&
262 test_must_fail git checkout spam &&
c8cbf20c 263 status_uno_is_clean &&
a047fafc 264 test_must_fail git rev-parse --verify refs/heads/spam &&
883b98ef 265 test_branch main
a047fafc
MM
266'
267
b829b943 268test_expect_success 'checkout of branch with a file in subdir having the same name fails' '
883b98ef 269 git checkout -B main &&
c8cbf20c 270 status_uno_is_clean &&
b829b943
NTND
271 test_might_fail git branch -D spam &&
272
273 >spam &&
274 mkdir sub &&
275 mv spam sub/spam &&
276 test_must_fail git -C sub checkout spam &&
c8cbf20c 277 status_uno_is_clean &&
b829b943 278 test_must_fail git rev-parse --verify refs/heads/spam &&
883b98ef 279 test_branch main
b829b943
NTND
280'
281
a047fafc 282test_expect_success 'checkout <branch> -- succeeds, even if a file with the same name exists' '
883b98ef 283 git checkout -B main &&
c8cbf20c 284 status_uno_is_clean &&
a047fafc
MM
285 test_might_fail git branch -D spam &&
286
287 >spam &&
288 git checkout spam -- &&
c8cbf20c 289 status_uno_is_clean &&
a047fafc
MM
290 test_branch spam &&
291 test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD &&
292 test_branch_upstream spam repo_c spam
293'
294
05e73682
JH
295test_expect_success 'loosely defined local base branch is reported correctly' '
296
883b98ef 297 git checkout main &&
c8cbf20c 298 status_uno_is_clean &&
05e73682
JH
299 git branch strict &&
300 git branch loose &&
301 git commit --allow-empty -m "a bit more" &&
302
303 test_config branch.strict.remote . &&
304 test_config branch.loose.remote . &&
883b98ef
JS
305 test_config branch.strict.merge refs/heads/main &&
306 test_config branch.loose.merge main &&
05e73682 307
fd726374
AR
308 git checkout strict >expect.raw 2>&1 &&
309 sed -e "s/strict/BRANCHNAME/g" <expect.raw >expect &&
c8cbf20c 310 status_uno_is_clean &&
fd726374
AR
311 git checkout loose >actual.raw 2>&1 &&
312 sed -e "s/loose/BRANCHNAME/g" <actual.raw >actual &&
c8cbf20c 313 status_uno_is_clean &&
fd726374 314 grep BRANCHNAME actual &&
05e73682
JH
315
316 test_cmp expect actual
317'
318
be4908f1
NTND
319test_expect_success 'reject when arg could be part of dwim branch' '
320 git remote add foo file://non-existent-place &&
321 git update-ref refs/remotes/foo/dwim-arg HEAD &&
322 echo foo >dwim-arg &&
323 git add dwim-arg &&
324 echo bar >dwim-arg &&
325 test_must_fail git checkout dwim-arg &&
326 test_must_fail git rev-parse refs/heads/dwim-arg -- &&
327 grep bar dwim-arg
328'
329
330test_expect_success 'disambiguate dwim branch and checkout path (1)' '
331 git update-ref refs/remotes/foo/dwim-arg1 HEAD &&
332 echo foo >dwim-arg1 &&
333 git add dwim-arg1 &&
334 echo bar >dwim-arg1 &&
335 git checkout -- dwim-arg1 &&
336 test_must_fail git rev-parse refs/heads/dwim-arg1 -- &&
337 grep foo dwim-arg1
338'
339
340test_expect_success 'disambiguate dwim branch and checkout path (2)' '
341 git update-ref refs/remotes/foo/dwim-arg2 HEAD &&
342 echo foo >dwim-arg2 &&
343 git add dwim-arg2 &&
344 echo bar >dwim-arg2 &&
345 git checkout dwim-arg2 -- &&
346 git rev-parse refs/heads/dwim-arg2 -- &&
347 grep bar dwim-arg2
348'
349
399e4a1c 350test_done