]> git.ipfire.org Git - thirdparty/git.git/blob - t/t2024-checkout-dwim.sh
t7700: clean up .keep file in bitmap-writing test
[thirdparty/git.git] / t / t2024-checkout-dwim.sh
1 #!/bin/sh
2
3 test_description='checkout <branch>
4
5 Ensures 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"?
10 test_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"?
17 test_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
26 status_uno_is_clean () {
27 git status -uno --porcelain >status.actual &&
28 test_must_be_empty status.actual
29 }
30
31 test_expect_success 'setup' '
32 test_commit my_master &&
33 git init repo_a &&
34 (
35 cd repo_a &&
36 test_commit a_master &&
37 git checkout -b foo &&
38 test_commit a_foo &&
39 git checkout -b bar &&
40 test_commit a_bar
41 ) &&
42 git init repo_b &&
43 (
44 cd repo_b &&
45 test_commit b_master &&
46 git checkout -b foo &&
47 test_commit b_foo &&
48 git checkout -b baz &&
49 test_commit b_baz
50 ) &&
51 git remote add repo_a repo_a &&
52 git remote add repo_b repo_b &&
53 git config remote.repo_b.fetch \
54 "+refs/heads/*:refs/remotes/other_b/*" &&
55 git fetch --all
56 '
57
58 test_expect_success 'checkout of non-existing branch fails' '
59 git checkout -B master &&
60 test_might_fail git branch -D xyzzy &&
61
62 test_must_fail git checkout xyzzy &&
63 status_uno_is_clean &&
64 test_must_fail git rev-parse --verify refs/heads/xyzzy &&
65 test_branch master
66 '
67
68 test_expect_success 'checkout of branch from multiple remotes fails #1' '
69 git checkout -B master &&
70 test_might_fail git branch -D foo &&
71
72 test_must_fail git checkout foo &&
73 status_uno_is_clean &&
74 test_must_fail git rev-parse --verify refs/heads/foo &&
75 test_branch master
76 '
77
78 test_expect_success 'checkout of branch from multiple remotes fails with advice' '
79 git checkout -B master &&
80 test_might_fail git branch -D foo &&
81 test_must_fail git checkout foo 2>stderr &&
82 test_branch master &&
83 status_uno_is_clean &&
84 test_i18ngrep "^hint: " stderr &&
85 test_must_fail git -c advice.checkoutAmbiguousRemoteBranchName=false \
86 checkout foo 2>stderr &&
87 test_branch master &&
88 status_uno_is_clean &&
89 test_i18ngrep ! "^hint: " stderr
90 '
91
92 test_expect_success PERL 'checkout -p with multiple remotes does not print advice' '
93 git checkout -B master &&
94 test_might_fail git branch -D foo &&
95
96 git checkout -p foo 2>stderr &&
97 test_i18ngrep ! "^hint: " stderr &&
98 status_uno_is_clean
99 '
100
101 test_expect_success 'checkout of branch from multiple remotes succeeds with checkout.defaultRemote #1' '
102 git checkout -B master &&
103 status_uno_is_clean &&
104 test_might_fail git branch -D foo &&
105
106 git -c checkout.defaultRemote=repo_a checkout foo &&
107 status_uno_is_clean &&
108 test_branch foo &&
109 test_cmp_rev remotes/repo_a/foo HEAD &&
110 test_branch_upstream foo repo_a foo
111 '
112
113 test_expect_success 'checkout of branch from a single remote succeeds #1' '
114 git checkout -B master &&
115 test_might_fail git branch -D bar &&
116
117 git checkout bar &&
118 status_uno_is_clean &&
119 test_branch bar &&
120 test_cmp_rev remotes/repo_a/bar HEAD &&
121 test_branch_upstream bar repo_a bar
122 '
123
124 test_expect_success 'checkout of branch from a single remote succeeds #2' '
125 git checkout -B master &&
126 test_might_fail git branch -D baz &&
127
128 git checkout baz &&
129 status_uno_is_clean &&
130 test_branch baz &&
131 test_cmp_rev remotes/other_b/baz HEAD &&
132 test_branch_upstream baz repo_b baz
133 '
134
135 test_expect_success '--no-guess suppresses branch auto-vivification' '
136 git checkout -B master &&
137 status_uno_is_clean &&
138 test_might_fail git branch -D bar &&
139
140 test_must_fail git checkout --no-guess bar &&
141 test_must_fail git rev-parse --verify refs/heads/bar &&
142 test_branch master
143 '
144
145 test_expect_success 'setup more remotes with unconventional refspecs' '
146 git checkout -B master &&
147 status_uno_is_clean &&
148 git init repo_c &&
149 (
150 cd repo_c &&
151 test_commit c_master &&
152 git checkout -b bar &&
153 test_commit c_bar &&
154 git checkout -b spam &&
155 test_commit c_spam
156 ) &&
157 git init repo_d &&
158 (
159 cd repo_d &&
160 test_commit d_master &&
161 git checkout -b baz &&
162 test_commit d_baz &&
163 git checkout -b eggs &&
164 test_commit d_eggs
165 ) &&
166 git remote add repo_c repo_c &&
167 git config remote.repo_c.fetch \
168 "+refs/heads/*:refs/remotes/extra_dir/repo_c/extra_dir/*" &&
169 git remote add repo_d repo_d &&
170 git config remote.repo_d.fetch \
171 "+refs/heads/*:refs/repo_d/*" &&
172 git fetch --all
173 '
174
175 test_expect_success 'checkout of branch from multiple remotes fails #2' '
176 git checkout -B master &&
177 status_uno_is_clean &&
178 test_might_fail git branch -D bar &&
179
180 test_must_fail git checkout bar &&
181 status_uno_is_clean &&
182 test_must_fail git rev-parse --verify refs/heads/bar &&
183 test_branch master
184 '
185
186 test_expect_success 'checkout of branch from multiple remotes fails #3' '
187 git checkout -B master &&
188 status_uno_is_clean &&
189 test_might_fail git branch -D baz &&
190
191 test_must_fail git checkout baz &&
192 status_uno_is_clean &&
193 test_must_fail git rev-parse --verify refs/heads/baz &&
194 test_branch master
195 '
196
197 test_expect_success 'checkout of branch from a single remote succeeds #3' '
198 git checkout -B master &&
199 status_uno_is_clean &&
200 test_might_fail git branch -D spam &&
201
202 git checkout spam &&
203 status_uno_is_clean &&
204 test_branch spam &&
205 test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD &&
206 test_branch_upstream spam repo_c spam
207 '
208
209 test_expect_success 'checkout of branch from a single remote succeeds #4' '
210 git checkout -B master &&
211 status_uno_is_clean &&
212 test_might_fail git branch -D eggs &&
213
214 git checkout eggs &&
215 status_uno_is_clean &&
216 test_branch eggs &&
217 test_cmp_rev refs/repo_d/eggs HEAD &&
218 test_branch_upstream eggs repo_d eggs
219 '
220
221 test_expect_success 'checkout of branch with a file having the same name fails' '
222 git checkout -B master &&
223 status_uno_is_clean &&
224 test_might_fail git branch -D spam &&
225
226 >spam &&
227 test_must_fail git checkout spam &&
228 status_uno_is_clean &&
229 test_must_fail git rev-parse --verify refs/heads/spam &&
230 test_branch master
231 '
232
233 test_expect_success 'checkout of branch with a file in subdir having the same name fails' '
234 git checkout -B master &&
235 status_uno_is_clean &&
236 test_might_fail git branch -D spam &&
237
238 >spam &&
239 mkdir sub &&
240 mv spam sub/spam &&
241 test_must_fail git -C sub checkout spam &&
242 status_uno_is_clean &&
243 test_must_fail git rev-parse --verify refs/heads/spam &&
244 test_branch master
245 '
246
247 test_expect_success 'checkout <branch> -- succeeds, even if a file with the same name exists' '
248 git checkout -B master &&
249 status_uno_is_clean &&
250 test_might_fail git branch -D spam &&
251
252 >spam &&
253 git checkout spam -- &&
254 status_uno_is_clean &&
255 test_branch spam &&
256 test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD &&
257 test_branch_upstream spam repo_c spam
258 '
259
260 test_expect_success 'loosely defined local base branch is reported correctly' '
261
262 git checkout master &&
263 status_uno_is_clean &&
264 git branch strict &&
265 git branch loose &&
266 git commit --allow-empty -m "a bit more" &&
267
268 test_config branch.strict.remote . &&
269 test_config branch.loose.remote . &&
270 test_config branch.strict.merge refs/heads/master &&
271 test_config branch.loose.merge master &&
272
273 git checkout strict | sed -e "s/strict/BRANCHNAME/g" >expect &&
274 status_uno_is_clean &&
275 git checkout loose | sed -e "s/loose/BRANCHNAME/g" >actual &&
276 status_uno_is_clean &&
277
278 test_cmp expect actual
279 '
280
281 test_expect_success 'reject when arg could be part of dwim branch' '
282 git remote add foo file://non-existent-place &&
283 git update-ref refs/remotes/foo/dwim-arg HEAD &&
284 echo foo >dwim-arg &&
285 git add dwim-arg &&
286 echo bar >dwim-arg &&
287 test_must_fail git checkout dwim-arg &&
288 test_must_fail git rev-parse refs/heads/dwim-arg -- &&
289 grep bar dwim-arg
290 '
291
292 test_expect_success 'disambiguate dwim branch and checkout path (1)' '
293 git update-ref refs/remotes/foo/dwim-arg1 HEAD &&
294 echo foo >dwim-arg1 &&
295 git add dwim-arg1 &&
296 echo bar >dwim-arg1 &&
297 git checkout -- dwim-arg1 &&
298 test_must_fail git rev-parse refs/heads/dwim-arg1 -- &&
299 grep foo dwim-arg1
300 '
301
302 test_expect_success 'disambiguate dwim branch and checkout path (2)' '
303 git update-ref refs/remotes/foo/dwim-arg2 HEAD &&
304 echo foo >dwim-arg2 &&
305 git add dwim-arg2 &&
306 echo bar >dwim-arg2 &&
307 git checkout dwim-arg2 -- &&
308 git rev-parse refs/heads/dwim-arg2 -- &&
309 grep bar dwim-arg2
310 '
311
312 test_done