]>
Commit | Line | Data |
---|---|---|
529fef20 NTND |
1 | #!/bin/sh |
2 | ||
f194b1ef | 3 | test_description='test git worktree add' |
529fef20 | 4 | |
883b98ef | 5 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
334afbc7 JS |
6 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
7 | ||
93e02b6e | 8 | TEST_CREATE_REPO_NO_TEMPLATE=1 |
529fef20 NTND |
9 | . ./test-lib.sh |
10 | ||
8d9fdd70 NTND |
11 | . "$TEST_DIRECTORY"/lib-rebase.sh |
12 | ||
529fef20 NTND |
13 | test_expect_success 'setup' ' |
14 | test_commit init | |
15 | ' | |
16 | ||
f194b1ef | 17 | test_expect_success '"add" an existing worktree' ' |
ee4fb843 | 18 | mkdir -p existing/subtree && |
883b98ef | 19 | test_must_fail git worktree add --detach existing main |
529fef20 NTND |
20 | ' |
21 | ||
f194b1ef | 22 | test_expect_success '"add" an existing empty worktree' ' |
ee4fb843 | 23 | mkdir existing_empty && |
883b98ef | 24 | git worktree add --detach existing_empty main |
ee4fb843 MK |
25 | ' |
26 | ||
1a450e2f JDG |
27 | test_expect_success '"add" using shorthand - fails when no previous branch' ' |
28 | test_must_fail git worktree add existing_short - | |
29 | ' | |
30 | ||
31 | test_expect_success '"add" using - shorthand' ' | |
32 | git checkout -b newbranch && | |
33 | echo hello >myworld && | |
34 | git add myworld && | |
35 | git commit -m myworld && | |
883b98ef | 36 | git checkout main && |
1a450e2f JDG |
37 | git worktree add short-hand - && |
38 | echo refs/heads/newbranch >expect && | |
39 | git -C short-hand rev-parse --symbolic-full-name HEAD >actual && | |
40 | test_cmp expect actual | |
41 | ' | |
42 | ||
f194b1ef | 43 | test_expect_success '"add" refuses to checkout locked branch' ' |
883b98ef | 44 | test_must_fail git worktree add zere main && |
3b8925c7 NTND |
45 | ! test -d zere && |
46 | ! test -d .git/worktrees/zere | |
47 | ' | |
48 | ||
e1c1ab9d NTND |
49 | test_expect_success 'checking out paths not complaining about linked checkouts' ' |
50 | ( | |
51 | cd existing_empty && | |
52 | echo dirty >>init.t && | |
883b98ef | 53 | git checkout main -- init.t |
e1c1ab9d NTND |
54 | ) |
55 | ' | |
56 | ||
f194b1ef | 57 | test_expect_success '"add" worktree' ' |
5883034c | 58 | git rev-parse HEAD >expect && |
883b98ef | 59 | git worktree add --detach here main && |
529fef20 NTND |
60 | ( |
61 | cd here && | |
62 | test_cmp ../init.t init.t && | |
5883034c NTND |
63 | test_must_fail git symbolic-ref HEAD && |
64 | git rev-parse HEAD >actual && | |
65 | test_cmp ../expect actual && | |
529fef20 NTND |
66 | git fsck |
67 | ) | |
68 | ' | |
69 | ||
507e6e9e | 70 | test_expect_success '"add" worktree with lock' ' |
883b98ef | 71 | git worktree add --detach --lock here-with-lock main && |
f9365c0a | 72 | test_when_finished "git worktree unlock here-with-lock || :" && |
507e6e9e NTND |
73 | test -f .git/worktrees/here-with-lock/locked |
74 | ' | |
75 | ||
0db4961c SM |
76 | test_expect_success '"add" worktree with lock and reason' ' |
77 | lock_reason="why not" && | |
78 | git worktree add --detach --lock --reason "$lock_reason" here-with-lock-reason main && | |
79 | test_when_finished "git worktree unlock here-with-lock-reason || :" && | |
80 | test -f .git/worktrees/here-with-lock-reason/locked && | |
81 | echo "$lock_reason" >expect && | |
82 | test_cmp expect .git/worktrees/here-with-lock-reason/locked | |
83 | ' | |
84 | ||
85 | test_expect_success '"add" worktree with reason but no lock' ' | |
86 | test_must_fail git worktree add --detach --reason "why not" here-with-reason-only main && | |
87 | test_path_is_missing .git/worktrees/here-with-reason-only/locked | |
88 | ' | |
89 | ||
f194b1ef | 90 | test_expect_success '"add" worktree from a subdir' ' |
529fef20 NTND |
91 | ( |
92 | mkdir sub && | |
93 | cd sub && | |
883b98ef | 94 | git worktree add --detach here main && |
529fef20 NTND |
95 | cd here && |
96 | test_cmp ../../init.t init.t | |
97 | ) | |
98 | ' | |
99 | ||
f194b1ef | 100 | test_expect_success '"add" from a linked checkout' ' |
529fef20 NTND |
101 | ( |
102 | cd here && | |
883b98ef | 103 | git worktree add --detach nested-here main && |
529fef20 NTND |
104 | cd nested-here && |
105 | git fsck | |
106 | ) | |
107 | ' | |
108 | ||
f194b1ef | 109 | test_expect_success '"add" worktree creating new branch' ' |
883b98ef | 110 | git worktree add -b newmain there main && |
529fef20 NTND |
111 | ( |
112 | cd there && | |
113 | test_cmp ../init.t init.t && | |
114 | git symbolic-ref HEAD >actual && | |
883b98ef | 115 | echo refs/heads/newmain >expect && |
529fef20 NTND |
116 | test_cmp expect actual && |
117 | git fsck | |
118 | ) | |
119 | ' | |
120 | ||
5883034c NTND |
121 | test_expect_success 'die the same branch is already checked out' ' |
122 | ( | |
123 | cd here && | |
2a499264 RJ |
124 | test_must_fail git checkout newmain 2>actual && |
125 | grep "already used by worktree at" actual | |
5883034c NTND |
126 | ) |
127 | ' | |
128 | ||
b23285a9 JH |
129 | test_expect_success 'refuse to reset a branch in use elsewhere' ' |
130 | ( | |
131 | cd here && | |
132 | ||
133 | # we know we are on detached HEAD but just in case ... | |
134 | git checkout --detach HEAD && | |
135 | git rev-parse --verify HEAD >old.head && | |
136 | ||
137 | git rev-parse --verify refs/heads/newmain >old.branch && | |
138 | test_must_fail git checkout -B newmain 2>error && | |
139 | git rev-parse --verify refs/heads/newmain >new.branch && | |
140 | git rev-parse --verify HEAD >new.head && | |
141 | ||
142 | grep "already used by worktree at" error && | |
143 | test_cmp old.branch new.branch && | |
144 | test_cmp old.head new.head && | |
145 | ||
146 | # and we must be still on the same detached HEAD state | |
147 | test_must_fail git symbolic-ref HEAD | |
148 | ) | |
149 | ' | |
150 | ||
746bbdc6 ES |
151 | test_expect_success SYMLINKS 'die the same branch is already checked out (symlink)' ' |
152 | head=$(git -C there rev-parse --git-path HEAD) && | |
153 | ref=$(git -C there symbolic-ref HEAD) && | |
154 | rm "$head" && | |
155 | ln -s "$ref" "$head" && | |
883b98ef | 156 | test_must_fail git -C here checkout newmain |
746bbdc6 ES |
157 | ' |
158 | ||
1d0fa898 NTND |
159 | test_expect_success 'not die the same branch is already checked out' ' |
160 | ( | |
161 | cd here && | |
883b98ef | 162 | git worktree add --force anothernewmain newmain |
1d0fa898 NTND |
163 | ) |
164 | ' | |
165 | ||
5883034c NTND |
166 | test_expect_success 'not die on re-checking out current branch' ' |
167 | ( | |
168 | cd there && | |
883b98ef | 169 | git checkout newmain |
5883034c NTND |
170 | ) |
171 | ' | |
172 | ||
f194b1ef | 173 | test_expect_success '"add" from a bare repo' ' |
3473ad0c DK |
174 | ( |
175 | git clone --bare . bare && | |
176 | cd bare && | |
883b98ef | 177 | git worktree add -b bare-main ../there2 main |
3473ad0c DK |
178 | ) |
179 | ' | |
180 | ||
f194b1ef | 181 | test_expect_success 'checkout from a bare repo without "add"' ' |
3473ad0c DK |
182 | ( |
183 | cd bare && | |
883b98ef | 184 | test_must_fail git checkout main |
3473ad0c DK |
185 | ) |
186 | ' | |
187 | ||
171c646f DK |
188 | test_expect_success '"add" default branch of a bare repo' ' |
189 | ( | |
190 | git clone --bare . bare2 && | |
191 | cd bare2 && | |
53255916 DS |
192 | git worktree add ../there3 main && |
193 | cd ../there3 && | |
194 | # Simple check that a Git command does not | |
195 | # immediately fail with the current setup | |
196 | git status | |
197 | ) && | |
198 | cat >expect <<-EOF && | |
199 | init.t | |
200 | EOF | |
201 | ls there3 >actual && | |
202 | test_cmp expect actual | |
203 | ' | |
204 | ||
205 | test_expect_success '"add" to bare repo with worktree config' ' | |
206 | ( | |
207 | git clone --bare . bare3 && | |
208 | cd bare3 && | |
209 | git config extensions.worktreeconfig true && | |
210 | ||
211 | # Add config values that are erroneous to have in | |
212 | # a config.worktree file outside of the main | |
213 | # working tree, to check that Git filters them out | |
214 | # when copying config during "git worktree add". | |
215 | git config --worktree core.bare true && | |
216 | git config --worktree core.worktree "$(pwd)" && | |
217 | ||
218 | # We want to check that bogus.key is copied | |
219 | git config --worktree bogus.key value && | |
220 | git config --unset core.bare && | |
221 | git worktree add ../there4 main && | |
222 | cd ../there4 && | |
223 | ||
224 | # Simple check that a Git command does not | |
225 | # immediately fail with the current setup | |
226 | git status && | |
227 | git worktree add --detach ../there5 && | |
228 | cd ../there5 && | |
229 | git status | |
230 | ) && | |
231 | ||
232 | # the worktree has the arbitrary value copied. | |
233 | test_cmp_config -C there4 value bogus.key && | |
234 | test_cmp_config -C there5 value bogus.key && | |
235 | ||
236 | # however, core.bare and core.worktree were removed. | |
237 | test_must_fail git -C there4 config core.bare && | |
238 | test_must_fail git -C there4 config core.worktree && | |
239 | ||
240 | cat >expect <<-EOF && | |
241 | init.t | |
242 | EOF | |
243 | ||
244 | ls there4 >actual && | |
245 | test_cmp expect actual && | |
246 | ls there5 >actual && | |
247 | test_cmp expect actual | |
171c646f DK |
248 | ' |
249 | ||
ad35f615 NTND |
250 | test_expect_success 'checkout with grafts' ' |
251 | test_when_finished rm .git/info/grafts && | |
252 | test_commit abc && | |
697b90d7 | 253 | SHA1=$(git rev-parse HEAD) && |
ad35f615 NTND |
254 | test_commit def && |
255 | test_commit xyz && | |
93e02b6e | 256 | mkdir .git/info && |
697b90d7 | 257 | echo "$(git rev-parse HEAD) $SHA1" >.git/info/grafts && |
ad35f615 NTND |
258 | cat >expected <<-\EOF && |
259 | xyz | |
260 | abc | |
261 | EOF | |
262 | git log --format=%s -2 >actual && | |
263 | test_cmp expected actual && | |
883b98ef | 264 | git worktree add --detach grafted main && |
ad35f615 NTND |
265 | git --git-dir=grafted/.git log --format=%s -2 >actual && |
266 | test_cmp expected actual | |
267 | ' | |
268 | ||
f194b1ef | 269 | test_expect_success '"add" from relative HEAD' ' |
c990a4c1 ES |
270 | test_commit a && |
271 | test_commit b && | |
272 | test_commit c && | |
273 | git rev-parse HEAD~1 >expected && | |
f194b1ef | 274 | git worktree add relhead HEAD~1 && |
c990a4c1 ES |
275 | git -C relhead rev-parse HEAD >actual && |
276 | test_cmp expected actual | |
277 | ' | |
278 | ||
0f4af3b9 ES |
279 | test_expect_success '"add -b" with <branch> omitted' ' |
280 | git worktree add -b burble flornk && | |
281 | test_cmp_rev HEAD burble | |
282 | ' | |
283 | ||
5c942570 ES |
284 | test_expect_success '"add --detach" with <branch> omitted' ' |
285 | git worktree add --detach fishhook && | |
286 | git rev-parse HEAD >expected && | |
287 | git -C fishhook rev-parse HEAD >actual && | |
288 | test_cmp expected actual && | |
289 | test_must_fail git -C fishhook symbolic-ref HEAD | |
290 | ' | |
291 | ||
1eb07d82 ES |
292 | test_expect_success '"add" with <branch> omitted' ' |
293 | git worktree add wiffle/bat && | |
294 | test_cmp_rev HEAD bat | |
295 | ' | |
296 | ||
f60a7b76 TG |
297 | test_expect_success '"add" checks out existing branch of dwimd name' ' |
298 | git branch dwim HEAD~1 && | |
299 | git worktree add dwim && | |
300 | test_cmp_rev HEAD~1 dwim && | |
301 | ( | |
302 | cd dwim && | |
303 | test_cmp_rev HEAD dwim | |
304 | ) | |
305 | ' | |
306 | ||
307 | test_expect_success '"add <path>" dwim fails with checked out branch' ' | |
308 | git checkout -b test-branch && | |
309 | test_must_fail git worktree add test-branch && | |
310 | test_path_is_missing test-branch | |
311 | ' | |
312 | ||
313 | test_expect_success '"add --force" with existing dwimd name doesnt die' ' | |
314 | git checkout test-branch && | |
315 | git worktree add --force test-branch | |
1eb07d82 ES |
316 | ' |
317 | ||
5c942570 ES |
318 | test_expect_success '"add" no auto-vivify with --detach and <branch> omitted' ' |
319 | git worktree add --detach mish/mash && | |
320 | test_must_fail git rev-parse mash -- && | |
321 | test_must_fail git -C mish/mash symbolic-ref HEAD | |
322 | ' | |
323 | ||
ed6db0e9 JA |
324 | # Helper function to test mutually exclusive options. |
325 | # | |
326 | # Note: Quoted arguments containing spaces are not supported. | |
327 | test_wt_add_excl () { | |
328 | local opts="$*" && | |
329 | test_expect_success "'worktree add' with '$opts' has mutually exclusive options" ' | |
330 | test_must_fail git worktree add $opts 2>actual && | |
331 | grep -E "fatal:( options)? .* cannot be used together" actual | |
332 | ' | |
333 | } | |
334 | ||
335 | test_wt_add_excl -b poodle -B poodle bamboo main | |
336 | test_wt_add_excl -b poodle --detach bamboo main | |
337 | test_wt_add_excl -B poodle --detach bamboo main | |
7ab89189 JA |
338 | test_wt_add_excl --orphan --detach bamboo |
339 | test_wt_add_excl --orphan --no-checkout bamboo | |
340 | test_wt_add_excl --orphan bamboo main | |
341 | test_wt_add_excl --orphan -b bamboo wtdir/ main | |
ab0b2c53 | 342 | |
beb6f24b | 343 | test_expect_success '"add -B" fails if the branch is checked out' ' |
883b98ef JS |
344 | git rev-parse newmain >before && |
345 | test_must_fail git worktree add -B newmain bamboo main && | |
346 | git rev-parse newmain >after && | |
beb6f24b NTND |
347 | test_cmp before after |
348 | ' | |
349 | ||
0ebf4a2a | 350 | test_expect_success 'add -B' ' |
883b98ef | 351 | git worktree add -B poodle bamboo2 main^ && |
0ebf4a2a NTND |
352 | git -C bamboo2 symbolic-ref HEAD >actual && |
353 | echo refs/heads/poodle >expected && | |
354 | test_cmp expected actual && | |
883b98ef | 355 | test_cmp_rev main^ poodle |
0ebf4a2a NTND |
356 | ' |
357 | ||
371979c2 | 358 | test_expect_success 'add --quiet' ' |
1b28fbd2 | 359 | test_when_finished "git worktree remove -f -f another-worktree" && |
883b98ef | 360 | git worktree add --quiet another-worktree main 2>actual && |
371979c2 EP |
361 | test_must_be_empty actual |
362 | ' | |
363 | ||
9ccdace1 JA |
364 | test_expect_success 'add --quiet -b' ' |
365 | test_when_finished "git branch -D quietnewbranch" && | |
366 | test_when_finished "git worktree remove -f -f another-worktree" && | |
367 | git worktree add --quiet -b quietnewbranch another-worktree 2>actual && | |
368 | test_must_be_empty actual | |
369 | ' | |
370 | ||
7ab89189 JA |
371 | test_expect_success '"add --orphan"' ' |
372 | test_when_finished "git worktree remove -f -f orphandir" && | |
373 | git worktree add --orphan -b neworphan orphandir && | |
374 | echo refs/heads/neworphan >expected && | |
375 | git -C orphandir symbolic-ref HEAD >actual && | |
376 | test_cmp expected actual | |
377 | ' | |
378 | ||
379 | test_expect_success '"add --orphan (no -b)"' ' | |
380 | test_when_finished "git worktree remove -f -f neworphan" && | |
381 | git worktree add --orphan neworphan && | |
382 | echo refs/heads/neworphan >expected && | |
383 | git -C neworphan symbolic-ref HEAD >actual && | |
384 | test_cmp expected actual | |
385 | ' | |
386 | ||
387 | test_expect_success '"add --orphan --quiet"' ' | |
388 | test_when_finished "git worktree remove -f -f orphandir" && | |
389 | git worktree add --quiet --orphan -b neworphan orphandir 2>log.actual && | |
390 | test_must_be_empty log.actual && | |
391 | echo refs/heads/neworphan >expected && | |
392 | git -C orphandir symbolic-ref HEAD >actual && | |
393 | test_cmp expected actual | |
394 | ' | |
395 | ||
396 | test_expect_success '"add --orphan" fails if the branch already exists' ' | |
397 | test_when_finished "git branch -D existingbranch" && | |
398 | git worktree add -b existingbranch orphandir main && | |
399 | git worktree remove orphandir && | |
400 | test_must_fail git worktree add --orphan -b existingbranch orphandir | |
401 | ' | |
402 | ||
403 | test_expect_success '"add --orphan" with empty repository' ' | |
404 | test_when_finished "rm -rf empty_repo" && | |
405 | echo refs/heads/newbranch >expected && | |
406 | GIT_DIR="empty_repo" git init --bare && | |
407 | git -C empty_repo worktree add --orphan -b newbranch worktreedir && | |
408 | git -C empty_repo/worktreedir symbolic-ref HEAD >actual && | |
409 | test_cmp expected actual | |
410 | ' | |
411 | ||
412 | test_expect_success '"add" worktree with orphan branch and lock' ' | |
413 | git worktree add --lock --orphan -b orphanbr orphan-with-lock && | |
414 | test_when_finished "git worktree unlock orphan-with-lock || :" && | |
415 | test -f .git/worktrees/orphan-with-lock/locked | |
416 | ' | |
417 | ||
418 | test_expect_success '"add" worktree with orphan branch, lock, and reason' ' | |
419 | lock_reason="why not" && | |
420 | git worktree add --detach --lock --reason "$lock_reason" orphan-with-lock-reason main && | |
421 | test_when_finished "git worktree unlock orphan-with-lock-reason || :" && | |
422 | test -f .git/worktrees/orphan-with-lock-reason/locked && | |
423 | echo "$lock_reason" >expect && | |
424 | test_cmp expect .git/worktrees/orphan-with-lock-reason/locked | |
425 | ' | |
426 | ||
35f0383c JA |
427 | # Note: Quoted arguments containing spaces are not supported. |
428 | test_wt_add_orphan_hint () { | |
429 | local context="$1" && | |
430 | local use_branch=$2 && | |
431 | shift 2 && | |
432 | local opts="$*" && | |
433 | test_expect_success "'worktree add' show orphan hint in bad/orphan HEAD w/ $context" ' | |
434 | test_when_finished "rm -rf repo" && | |
435 | git init repo && | |
436 | (cd repo && test_commit commit) && | |
437 | git -C repo switch --orphan noref && | |
438 | test_must_fail git -C repo worktree add $opts foobar/ 2>actual && | |
439 | ! grep "error: unknown switch" actual && | |
d44b5171 | 440 | grep "hint: If you meant to create a worktree containing a new unborn branch" actual && |
35f0383c JA |
441 | if [ $use_branch -eq 1 ] |
442 | then | |
d1b72cb3 | 443 | grep -E "^hint: +git worktree add --orphan -b [^ ]+ [^ ]+$" actual |
35f0383c | 444 | else |
d1b72cb3 | 445 | grep -E "^hint: +git worktree add --orphan [^ ]+$" actual |
35f0383c JA |
446 | fi |
447 | ||
448 | ' | |
449 | } | |
450 | ||
451 | test_wt_add_orphan_hint 'no opts' 0 | |
452 | test_wt_add_orphan_hint '-b' 1 -b foobar_branch | |
453 | test_wt_add_orphan_hint '-B' 1 -B foobar_branch | |
454 | ||
455 | test_expect_success "'worktree add' doesn't show orphan hint in bad/orphan HEAD w/ --quiet" ' | |
456 | test_when_finished "rm -rf repo" && | |
457 | git init repo && | |
458 | (cd repo && test_commit commit) && | |
459 | test_must_fail git -C repo worktree add --quiet foobar_branch foobar/ 2>actual && | |
460 | ! grep "error: unknown switch" actual && | |
d44b5171 | 461 | ! grep "hint: If you meant to create a worktree containing a new unborn branch" actual |
35f0383c JA |
462 | ' |
463 | ||
744e4697 NTND |
464 | test_expect_success 'local clone from linked checkout' ' |
465 | git clone --local here here-clone && | |
466 | ( cd here-clone && git fsck ) | |
467 | ' | |
468 | ||
b3b05971 ES |
469 | test_expect_success 'local clone --shared from linked checkout' ' |
470 | git -C bare worktree add --detach ../baretree && | |
471 | git clone --local --shared baretree bare-clone && | |
472 | grep /bare/ bare-clone/.git/objects/info/alternates | |
473 | ' | |
474 | ||
ef2a0ac9 RZ |
475 | test_expect_success '"add" worktree with --no-checkout' ' |
476 | git worktree add --no-checkout -b swamp swamp && | |
477 | ! test -e swamp/init.t && | |
478 | git -C swamp reset --hard && | |
479 | test_cmp init.t swamp/init.t | |
480 | ' | |
481 | ||
482 | test_expect_success '"add" worktree with --checkout' ' | |
483 | git worktree add --checkout -b swmap2 swamp2 && | |
484 | test_cmp init.t swamp2/init.t | |
485 | ' | |
486 | ||
8d9fdd70 NTND |
487 | test_expect_success 'put a worktree under rebase' ' |
488 | git worktree add under-rebase && | |
489 | ( | |
490 | cd under-rebase && | |
491 | set_fake_editor && | |
492 | FAKE_LINES="edit 1" git rebase -i HEAD^ && | |
425ae8a3 AL |
493 | git worktree list >actual && |
494 | grep "under-rebase.*detached HEAD" actual | |
8d9fdd70 NTND |
495 | ) |
496 | ' | |
497 | ||
498 | test_expect_success 'add a worktree, checking out a rebased branch' ' | |
499 | test_must_fail git worktree add new-rebase under-rebase && | |
500 | ! test -d new-rebase | |
501 | ' | |
502 | ||
503 | test_expect_success 'checking out a rebased branch from another worktree' ' | |
504 | git worktree add new-place && | |
505 | test_must_fail git -C new-place checkout under-rebase | |
506 | ' | |
507 | ||
508 | test_expect_success 'not allow to delete a branch under rebase' ' | |
509 | ( | |
510 | cd under-rebase && | |
511 | test_must_fail git branch -D under-rebase | |
512 | ) | |
513 | ' | |
514 | ||
14ace5b7 NTND |
515 | test_expect_success 'rename a branch under rebase not allowed' ' |
516 | test_must_fail git branch -M under-rebase rebase-with-new-name | |
517 | ' | |
518 | ||
8d9fdd70 NTND |
519 | test_expect_success 'check out from current worktree branch ok' ' |
520 | ( | |
521 | cd under-rebase && | |
522 | git checkout under-rebase && | |
523 | git checkout - && | |
524 | git rebase --abort | |
525 | ) | |
526 | ' | |
527 | ||
04a3dfb8 NTND |
528 | test_expect_success 'checkout a branch under bisect' ' |
529 | git worktree add under-bisect && | |
530 | ( | |
531 | cd under-bisect && | |
532 | git bisect start && | |
533 | git bisect bad && | |
534 | git bisect good HEAD~2 && | |
425ae8a3 AL |
535 | git worktree list >actual && |
536 | grep "under-bisect.*detached HEAD" actual && | |
04a3dfb8 NTND |
537 | test_must_fail git worktree add new-bisect under-bisect && |
538 | ! test -d new-bisect | |
539 | ) | |
540 | ' | |
541 | ||
14ace5b7 NTND |
542 | test_expect_success 'rename a branch under bisect not allowed' ' |
543 | test_must_fail git branch -M under-bisect bisect-with-new-name | |
544 | ' | |
e284e892 TG |
545 | # Is branch "refs/heads/$1" set to pull from "$2/$3"? |
546 | test_branch_upstream () { | |
547 | printf "%s\n" "$2" "refs/heads/$3" >expect.upstream && | |
548 | { | |
549 | git config "branch.$1.remote" && | |
550 | git config "branch.$1.merge" | |
551 | } >actual.upstream && | |
552 | test_cmp expect.upstream actual.upstream | |
553 | } | |
554 | ||
555 | test_expect_success '--track sets up tracking' ' | |
556 | test_when_finished rm -rf track && | |
883b98ef JS |
557 | git worktree add --track -b track track main && |
558 | test_branch_upstream track . main | |
e284e892 TG |
559 | ' |
560 | ||
561 | # setup remote repository $1 and repository $2 with $1 set up as | |
883b98ef | 562 | # remote. The remote has two branches, main and foo. |
e284e892 TG |
563 | setup_remote_repo () { |
564 | git init $1 && | |
565 | ( | |
566 | cd $1 && | |
883b98ef | 567 | test_commit $1_main && |
e284e892 TG |
568 | git checkout -b foo && |
569 | test_commit upstream_foo | |
570 | ) && | |
571 | git init $2 && | |
572 | ( | |
573 | cd $2 && | |
883b98ef | 574 | test_commit $2_main && |
e284e892 TG |
575 | git remote add $1 ../$1 && |
576 | git config remote.$1.fetch \ | |
577 | "refs/heads/*:refs/remotes/$1/*" && | |
578 | git fetch --all | |
579 | ) | |
580 | } | |
581 | ||
7ab89189 JA |
582 | test_expect_success '"add" <path> <remote/branch> w/ no HEAD' ' |
583 | test_when_finished rm -rf repo_upstream repo_local foo && | |
584 | setup_remote_repo repo_upstream repo_local && | |
585 | git -C repo_local config --bool core.bare true && | |
586 | git -C repo_local branch -D main && | |
587 | git -C repo_local worktree add ./foo repo_upstream/foo | |
588 | ' | |
589 | ||
e284e892 TG |
590 | test_expect_success '--no-track avoids setting up tracking' ' |
591 | test_when_finished rm -rf repo_upstream repo_local foo && | |
592 | setup_remote_repo repo_upstream repo_local && | |
593 | ( | |
594 | cd repo_local && | |
595 | git worktree add --no-track -b foo ../foo repo_upstream/foo | |
596 | ) && | |
597 | ( | |
598 | cd foo && | |
599 | test_must_fail git config "branch.foo.remote" && | |
600 | test_must_fail git config "branch.foo.merge" && | |
601 | test_cmp_rev refs/remotes/repo_upstream/foo refs/heads/foo | |
602 | ) | |
603 | ' | |
14ace5b7 | 604 | |
4e853331 TG |
605 | test_expect_success '"add" <path> <non-existent-branch> fails' ' |
606 | test_must_fail git worktree add foo non-existent | |
607 | ' | |
608 | ||
609 | test_expect_success '"add" <path> <branch> dwims' ' | |
610 | test_when_finished rm -rf repo_upstream repo_dwim foo && | |
611 | setup_remote_repo repo_upstream repo_dwim && | |
612 | git init repo_dwim && | |
613 | ( | |
614 | cd repo_dwim && | |
615 | git worktree add ../foo foo | |
616 | ) && | |
617 | ( | |
618 | cd foo && | |
619 | test_branch_upstream foo repo_upstream foo && | |
620 | test_cmp_rev refs/remotes/repo_upstream/foo refs/heads/foo | |
621 | ) | |
622 | ' | |
623 | ||
8d7b558b ÆAB |
624 | test_expect_success '"add" <path> <branch> dwims with checkout.defaultRemote' ' |
625 | test_when_finished rm -rf repo_upstream repo_dwim foo && | |
626 | setup_remote_repo repo_upstream repo_dwim && | |
627 | git init repo_dwim && | |
628 | ( | |
629 | cd repo_dwim && | |
630 | git remote add repo_upstream2 ../repo_upstream && | |
631 | git fetch repo_upstream2 && | |
632 | test_must_fail git worktree add ../foo foo && | |
633 | git -c checkout.defaultRemote=repo_upstream worktree add ../foo foo && | |
8d7b558b | 634 | git status -uno --porcelain >status.actual && |
9f4bcf81 | 635 | test_must_be_empty status.actual |
8d7b558b ÆAB |
636 | ) && |
637 | ( | |
638 | cd foo && | |
639 | test_branch_upstream foo repo_upstream foo && | |
640 | test_cmp_rev refs/remotes/repo_upstream/foo refs/heads/foo | |
641 | ) | |
642 | ' | |
643 | ||
71d6682d TG |
644 | test_expect_success 'git worktree add does not match remote' ' |
645 | test_when_finished rm -rf repo_a repo_b foo && | |
646 | setup_remote_repo repo_a repo_b && | |
647 | ( | |
648 | cd repo_b && | |
649 | git worktree add ../foo | |
650 | ) && | |
651 | ( | |
652 | cd foo && | |
653 | test_must_fail git config "branch.foo.remote" && | |
654 | test_must_fail git config "branch.foo.merge" && | |
2c9e125b | 655 | test_cmp_rev ! refs/remotes/repo_a/foo refs/heads/foo |
71d6682d TG |
656 | ) |
657 | ' | |
658 | ||
659 | test_expect_success 'git worktree add --guess-remote sets up tracking' ' | |
660 | test_when_finished rm -rf repo_a repo_b foo && | |
661 | setup_remote_repo repo_a repo_b && | |
662 | ( | |
663 | cd repo_b && | |
664 | git worktree add --guess-remote ../foo | |
665 | ) && | |
666 | ( | |
667 | cd foo && | |
668 | test_branch_upstream foo repo_a foo && | |
669 | test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo | |
670 | ) | |
671 | ' | |
9ccdace1 JA |
672 | test_expect_success 'git worktree add --guess-remote sets up tracking (quiet)' ' |
673 | test_when_finished rm -rf repo_a repo_b foo && | |
674 | setup_remote_repo repo_a repo_b && | |
675 | ( | |
676 | cd repo_b && | |
677 | git worktree add --quiet --guess-remote ../foo 2>actual && | |
678 | test_must_be_empty actual | |
679 | ) && | |
680 | ( | |
681 | cd foo && | |
682 | test_branch_upstream foo repo_a foo && | |
683 | test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo | |
684 | ) | |
685 | ' | |
686 | ||
687 | test_expect_success 'git worktree --no-guess-remote (quiet)' ' | |
688 | test_when_finished rm -rf repo_a repo_b foo && | |
689 | setup_remote_repo repo_a repo_b && | |
690 | ( | |
691 | cd repo_b && | |
692 | git worktree add --quiet --no-guess-remote ../foo | |
693 | ) && | |
694 | ( | |
695 | cd foo && | |
696 | test_must_fail git config "branch.foo.remote" && | |
697 | test_must_fail git config "branch.foo.merge" && | |
698 | test_cmp_rev ! refs/remotes/repo_a/foo refs/heads/foo | |
699 | ) | |
700 | ' | |
71d6682d | 701 | |
e92445a7 TG |
702 | test_expect_success 'git worktree add with worktree.guessRemote sets up tracking' ' |
703 | test_when_finished rm -rf repo_a repo_b foo && | |
704 | setup_remote_repo repo_a repo_b && | |
705 | ( | |
706 | cd repo_b && | |
707 | git config worktree.guessRemote true && | |
708 | git worktree add ../foo | |
709 | ) && | |
710 | ( | |
711 | cd foo && | |
712 | test_branch_upstream foo repo_a foo && | |
713 | test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo | |
714 | ) | |
715 | ' | |
716 | ||
717 | test_expect_success 'git worktree --no-guess-remote option overrides config' ' | |
718 | test_when_finished rm -rf repo_a repo_b foo && | |
719 | setup_remote_repo repo_a repo_b && | |
720 | ( | |
721 | cd repo_b && | |
722 | git config worktree.guessRemote true && | |
723 | git worktree add --no-guess-remote ../foo | |
724 | ) && | |
725 | ( | |
726 | cd foo && | |
727 | test_must_fail git config "branch.foo.remote" && | |
728 | test_must_fail git config "branch.foo.merge" && | |
2c9e125b | 729 | test_cmp_rev ! refs/remotes/repo_a/foo refs/heads/foo |
e92445a7 TG |
730 | ) |
731 | ' | |
732 | ||
128e5496 JA |
733 | test_dwim_orphan () { |
734 | local info_text="No possible source branch, inferring '--orphan'" && | |
735 | local fetch_error_text="fatal: No local or remote refs exist despite at least one remote" && | |
d44b5171 | 736 | local orphan_hint="hint: If you meant to create a worktree containing a new unborn branch" && |
d1b72cb3 | 737 | local invalid_ref_regex="^fatal: invalid reference: " && |
62bc6dd3 | 738 | local bad_combo_regex="^fatal: options '[-a-z]*' and '[-a-z]*' cannot be used together" && |
128e5496 JA |
739 | |
740 | local git_ns="repo" && | |
741 | local dashc_args="-C $git_ns" && | |
742 | local use_cd=0 && | |
743 | ||
744 | local bad_head=0 && | |
745 | local empty_repo=1 && | |
746 | local local_ref=0 && | |
747 | local use_quiet=0 && | |
748 | local remote=0 && | |
749 | local remote_ref=0 && | |
926c40d0 | 750 | local use_detach=0 && |
128e5496 JA |
751 | local use_new_branch=0 && |
752 | ||
753 | local outcome="$1" && | |
754 | local outcome_text && | |
755 | local success && | |
756 | shift && | |
757 | local args="" && | |
758 | local context="" && | |
759 | case "$outcome" in | |
760 | "infer") | |
761 | success=1 && | |
762 | outcome_text='"add" DWIM infer --orphan' | |
763 | ;; | |
764 | "no_infer") | |
765 | success=1 && | |
766 | outcome_text='"add" DWIM doesnt infer --orphan' | |
767 | ;; | |
768 | "fetch_error") | |
769 | success=0 && | |
770 | outcome_text='"add" error need fetch' | |
771 | ;; | |
772 | "fatal_orphan_bad_combo") | |
773 | success=0 && | |
774 | outcome_text='"add" error inferred "--orphan" gives illegal opts combo' | |
775 | ;; | |
926c40d0 JA |
776 | "warn_bad_head") |
777 | success=0 && | |
778 | outcome_text='"add" error, warn on bad HEAD, hint use orphan' | |
779 | ;; | |
128e5496 JA |
780 | *) |
781 | echo "test_dwim_orphan(): invalid outcome: '$outcome'" >&2 && | |
782 | return 1 | |
783 | ;; | |
784 | esac && | |
785 | while [ $# -gt 0 ] | |
786 | do | |
787 | case "$1" in | |
788 | # How and from where to create the worktree | |
789 | "-C_repo") | |
790 | use_cd=0 && | |
791 | git_ns="repo" && | |
792 | dashc_args="-C $git_ns" && | |
793 | context="$context, 'git -C repo'" | |
794 | ;; | |
795 | "-C_wt") | |
796 | use_cd=0 && | |
797 | git_ns="wt" && | |
798 | dashc_args="-C $git_ns" && | |
799 | context="$context, 'git -C wt'" | |
800 | ;; | |
801 | "cd_repo") | |
802 | use_cd=1 && | |
803 | git_ns="repo" && | |
804 | dashc_args="" && | |
805 | context="$context, 'cd repo && git'" | |
806 | ;; | |
807 | "cd_wt") | |
808 | use_cd=1 && | |
809 | git_ns="wt" && | |
810 | dashc_args="" && | |
811 | context="$context, 'cd wt && git'" | |
812 | ;; | |
813 | ||
814 | # Bypass the "pull first" warning | |
815 | "force") | |
816 | args="$args --force" && | |
817 | context="$context, --force" | |
818 | ;; | |
819 | ||
820 | # Try to use remote refs when DWIM | |
821 | "guess_remote") | |
822 | args="$args --guess-remote" && | |
823 | context="$context, --guess-remote" | |
824 | ;; | |
825 | "no_guess_remote") | |
826 | args="$args --no-guess-remote" && | |
827 | context="$context, --no-guess-remote" | |
828 | ;; | |
829 | ||
830 | # Whether there is at least one local branch present | |
831 | "local_ref") | |
832 | empty_repo=0 && | |
833 | local_ref=1 && | |
834 | context="$context, >=1 local branches" | |
835 | ;; | |
836 | "no_local_ref") | |
837 | empty_repo=0 && | |
838 | context="$context, 0 local branches" | |
839 | ;; | |
840 | ||
841 | # Whether the HEAD points at a valid ref (skip this opt when no refs) | |
842 | "good_head") | |
843 | # requires: local_ref | |
844 | context="$context, valid HEAD" | |
845 | ;; | |
846 | "bad_head") | |
847 | bad_head=1 && | |
848 | context="$context, invalid (or orphan) HEAD" | |
849 | ;; | |
850 | ||
926c40d0 | 851 | # Whether the code path is tested with the base add command, -b, or --detach |
128e5496 JA |
852 | "no_-b") |
853 | use_new_branch=0 && | |
854 | context="$context, no --branch" | |
855 | ;; | |
856 | "-b") | |
857 | use_new_branch=1 && | |
858 | context="$context, --branch" | |
859 | ;; | |
926c40d0 JA |
860 | "detach") |
861 | use_detach=1 && | |
862 | context="$context, --detach" | |
863 | ;; | |
128e5496 JA |
864 | |
865 | # Whether to check that all output is suppressed (except errors) | |
866 | # or that the output is as expected | |
867 | "quiet") | |
868 | use_quiet=1 && | |
869 | args="$args --quiet" && | |
870 | context="$context, --quiet" | |
871 | ;; | |
872 | "no_quiet") | |
873 | use_quiet=0 && | |
874 | context="$context, no --quiet (expect output)" | |
875 | ;; | |
876 | ||
877 | # Whether there is at least one remote attached to the repo | |
878 | "remote") | |
879 | empty_repo=0 && | |
880 | remote=1 && | |
881 | context="$context, >=1 remotes" | |
882 | ;; | |
883 | "no_remote") | |
884 | empty_repo=0 && | |
885 | remote=0 && | |
886 | context="$context, 0 remotes" | |
887 | ;; | |
888 | ||
889 | # Whether there is at least one valid remote ref | |
890 | "remote_ref") | |
891 | # requires: remote | |
892 | empty_repo=0 && | |
893 | remote_ref=1 && | |
894 | context="$context, >=1 fetched remote branches" | |
895 | ;; | |
896 | "no_remote_ref") | |
897 | empty_repo=0 && | |
898 | remote_ref=0 && | |
899 | context="$context, 0 fetched remote branches" | |
900 | ;; | |
901 | ||
902 | # Options or flags that become illegal when --orphan is inferred | |
903 | "no_checkout") | |
904 | args="$args --no-checkout" && | |
905 | context="$context, --no-checkout" | |
906 | ;; | |
907 | "track") | |
908 | args="$args --track" && | |
909 | context="$context, --track" | |
910 | ;; | |
911 | ||
912 | # All other options are illegal | |
913 | *) | |
914 | echo "test_dwim_orphan(): invalid arg: '$1'" >&2 && | |
915 | return 1 | |
916 | ;; | |
917 | esac && | |
918 | shift | |
919 | done && | |
920 | context="${context#', '}" && | |
921 | if [ $use_new_branch -eq 1 ] | |
922 | then | |
923 | args="$args -b foo" | |
926c40d0 JA |
924 | elif [ $use_detach -eq 1 ] |
925 | then | |
926 | args="$args --detach" | |
128e5496 JA |
927 | else |
928 | context="DWIM (no --branch), $context" | |
929 | fi && | |
930 | if [ $empty_repo -eq 1 ] | |
931 | then | |
932 | context="empty repo, $context" | |
933 | fi && | |
934 | args="$args ../foo" && | |
935 | context="${context%', '}" && | |
936 | test_expect_success "$outcome_text w/ $context" ' | |
937 | test_when_finished "rm -rf repo" && | |
938 | git init repo && | |
939 | if [ $local_ref -eq 1 ] && [ "$git_ns" = "repo" ] | |
940 | then | |
941 | (cd repo && test_commit commit) && | |
942 | if [ $bad_head -eq 1 ] | |
943 | then | |
944 | git -C repo symbolic-ref HEAD refs/heads/badbranch | |
945 | fi | |
946 | elif [ $local_ref -eq 1 ] && [ "$git_ns" = "wt" ] | |
947 | then | |
948 | test_when_finished "git -C repo worktree remove -f ../wt" && | |
949 | git -C repo worktree add --orphan -b main ../wt && | |
950 | (cd wt && test_commit commit) && | |
951 | if [ $bad_head -eq 1 ] | |
952 | then | |
953 | git -C wt symbolic-ref HEAD refs/heads/badbranch | |
954 | fi | |
955 | elif [ $local_ref -eq 0 ] && [ "$git_ns" = "wt" ] | |
956 | then | |
957 | test_when_finished "git -C repo worktree remove -f ../wt" && | |
958 | git -C repo worktree add --orphan -b orphanbranch ../wt | |
959 | fi && | |
960 | ||
961 | if [ $remote -eq 1 ] | |
962 | then | |
963 | test_when_finished "rm -rf upstream" && | |
964 | git init upstream && | |
965 | (cd upstream && test_commit commit) && | |
966 | git -C upstream switch -c foo && | |
967 | git -C repo remote add upstream ../upstream | |
968 | fi && | |
969 | ||
970 | if [ $remote_ref -eq 1 ] | |
971 | then | |
972 | git -C repo fetch | |
973 | fi && | |
974 | if [ $success -eq 1 ] | |
975 | then | |
976 | test_when_finished git -C repo worktree remove ../foo | |
977 | fi && | |
978 | ( | |
979 | if [ $use_cd -eq 1 ] | |
980 | then | |
981 | cd $git_ns | |
982 | fi && | |
983 | if [ "$outcome" = "infer" ] | |
984 | then | |
985 | git $dashc_args worktree add $args 2>actual && | |
986 | if [ $use_quiet -eq 1 ] | |
987 | then | |
988 | test_must_be_empty actual | |
989 | else | |
990 | grep "$info_text" actual | |
991 | fi | |
992 | elif [ "$outcome" = "no_infer" ] | |
993 | then | |
994 | git $dashc_args worktree add $args 2>actual && | |
995 | if [ $use_quiet -eq 1 ] | |
996 | then | |
997 | test_must_be_empty actual | |
998 | else | |
999 | ! grep "$info_text" actual | |
1000 | fi | |
1001 | elif [ "$outcome" = "fetch_error" ] | |
1002 | then | |
1003 | test_must_fail git $dashc_args worktree add $args 2>actual && | |
1004 | grep "$fetch_error_text" actual | |
1005 | elif [ "$outcome" = "fatal_orphan_bad_combo" ] | |
1006 | then | |
1007 | test_must_fail git $dashc_args worktree add $args 2>actual && | |
1008 | if [ $use_quiet -eq 1 ] | |
1009 | then | |
1010 | ! grep "$info_text" actual | |
1011 | else | |
1012 | grep "$info_text" actual | |
1013 | fi && | |
1014 | grep "$bad_combo_regex" actual | |
1015 | elif [ "$outcome" = "warn_bad_head" ] | |
1016 | then | |
1017 | test_must_fail git $dashc_args worktree add $args 2>actual && | |
1018 | if [ $use_quiet -eq 1 ] | |
1019 | then | |
1020 | grep "$invalid_ref_regex" actual && | |
1021 | ! grep "$orphan_hint" actual | |
1022 | else | |
9111ea1c | 1023 | headpath=$(git $dashc_args rev-parse --path-format=absolute --git-path HEAD) && |
128e5496 JA |
1024 | headcontents=$(cat "$headpath") && |
1025 | grep "HEAD points to an invalid (or orphaned) reference" actual && | |
d1b72cb3 JA |
1026 | grep "HEAD path: .$headpath." actual && |
1027 | grep "HEAD contents: .$headcontents." actual && | |
128e5496 JA |
1028 | grep "$orphan_hint" actual && |
1029 | ! grep "$info_text" actual | |
1030 | fi && | |
1031 | grep "$invalid_ref_regex" actual | |
1032 | else | |
1033 | # Unreachable | |
1034 | false | |
1035 | fi | |
1036 | ) && | |
1037 | if [ $success -ne 1 ] | |
1038 | then | |
1039 | test_path_is_missing foo | |
1040 | fi | |
1041 | ' | |
1042 | } | |
1043 | ||
1044 | for quiet_mode in "no_quiet" "quiet" | |
1045 | do | |
1046 | for changedir_type in "cd_repo" "cd_wt" "-C_repo" "-C_wt" | |
1047 | do | |
1048 | dwim_test_args="$quiet_mode $changedir_type" | |
1049 | test_dwim_orphan 'infer' $dwim_test_args no_-b | |
1050 | test_dwim_orphan 'no_infer' $dwim_test_args no_-b local_ref good_head | |
1051 | test_dwim_orphan 'infer' $dwim_test_args no_-b no_local_ref no_remote no_remote_ref no_guess_remote | |
1052 | test_dwim_orphan 'infer' $dwim_test_args no_-b no_local_ref remote no_remote_ref no_guess_remote | |
1053 | test_dwim_orphan 'fetch_error' $dwim_test_args no_-b no_local_ref remote no_remote_ref guess_remote | |
1054 | test_dwim_orphan 'infer' $dwim_test_args no_-b no_local_ref remote no_remote_ref guess_remote force | |
1055 | test_dwim_orphan 'no_infer' $dwim_test_args no_-b no_local_ref remote remote_ref guess_remote | |
1056 | ||
1057 | test_dwim_orphan 'infer' $dwim_test_args -b | |
1058 | test_dwim_orphan 'no_infer' $dwim_test_args -b local_ref good_head | |
1059 | test_dwim_orphan 'infer' $dwim_test_args -b no_local_ref no_remote no_remote_ref no_guess_remote | |
1060 | test_dwim_orphan 'infer' $dwim_test_args -b no_local_ref remote no_remote_ref no_guess_remote | |
1061 | test_dwim_orphan 'infer' $dwim_test_args -b no_local_ref remote no_remote_ref guess_remote | |
1062 | test_dwim_orphan 'infer' $dwim_test_args -b no_local_ref remote remote_ref guess_remote | |
926c40d0 JA |
1063 | |
1064 | test_dwim_orphan 'warn_bad_head' $dwim_test_args no_-b local_ref bad_head | |
1065 | test_dwim_orphan 'warn_bad_head' $dwim_test_args -b local_ref bad_head | |
1066 | test_dwim_orphan 'warn_bad_head' $dwim_test_args detach local_ref bad_head | |
128e5496 JA |
1067 | done |
1068 | ||
1069 | test_dwim_orphan 'fatal_orphan_bad_combo' $quiet_mode no_-b no_checkout | |
1070 | test_dwim_orphan 'fatal_orphan_bad_combo' $quiet_mode no_-b track | |
1071 | test_dwim_orphan 'fatal_orphan_bad_combo' $quiet_mode -b no_checkout | |
1072 | test_dwim_orphan 'fatal_orphan_bad_combo' $quiet_mode -b track | |
1073 | done | |
1074 | ||
ade546be | 1075 | post_checkout_hook () { |
93e02b6e ÆAB |
1076 | test_when_finished "rm -rf .git/hooks" && |
1077 | mkdir .git/hooks && | |
66865d12 | 1078 | test_hook -C "$1" post-checkout <<-\EOF |
a4bf1e3c ES |
1079 | { |
1080 | echo $* | |
1081 | git rev-parse --git-dir --show-toplevel | |
1082 | } >hook.actual | |
ade546be ES |
1083 | EOF |
1084 | } | |
1085 | ||
1086 | test_expect_success '"add" invokes post-checkout hook (branch)' ' | |
1087 | post_checkout_hook && | |
a4bf1e3c | 1088 | { |
8125a58b | 1089 | echo $ZERO_OID $(git rev-parse HEAD) 1 && |
a4bf1e3c ES |
1090 | echo $(pwd)/.git/worktrees/gumby && |
1091 | echo $(pwd)/gumby | |
1092 | } >hook.expect && | |
ade546be | 1093 | git worktree add gumby && |
a4bf1e3c | 1094 | test_cmp hook.expect gumby/hook.actual |
ade546be ES |
1095 | ' |
1096 | ||
1097 | test_expect_success '"add" invokes post-checkout hook (detached)' ' | |
1098 | post_checkout_hook && | |
a4bf1e3c | 1099 | { |
8125a58b | 1100 | echo $ZERO_OID $(git rev-parse HEAD) 1 && |
a4bf1e3c ES |
1101 | echo $(pwd)/.git/worktrees/grumpy && |
1102 | echo $(pwd)/grumpy | |
1103 | } >hook.expect && | |
ade546be | 1104 | git worktree add --detach grumpy && |
a4bf1e3c | 1105 | test_cmp hook.expect grumpy/hook.actual |
ade546be ES |
1106 | ' |
1107 | ||
1108 | test_expect_success '"add --no-checkout" suppresses post-checkout hook' ' | |
1109 | post_checkout_hook && | |
1110 | rm -f hook.actual && | |
1111 | git worktree add --no-checkout gloopy && | |
a4bf1e3c ES |
1112 | test_path_is_missing gloopy/hook.actual |
1113 | ' | |
1114 | ||
1115 | test_expect_success '"add" in other worktree invokes post-checkout hook' ' | |
1116 | post_checkout_hook && | |
1117 | { | |
8125a58b | 1118 | echo $ZERO_OID $(git rev-parse HEAD) 1 && |
a4bf1e3c ES |
1119 | echo $(pwd)/.git/worktrees/guppy && |
1120 | echo $(pwd)/guppy | |
1121 | } >hook.expect && | |
1122 | git -C gloopy worktree add --detach ../guppy && | |
1123 | test_cmp hook.expect guppy/hook.actual | |
1124 | ' | |
1125 | ||
1126 | test_expect_success '"add" in bare repo invokes post-checkout hook' ' | |
1127 | rm -rf bare && | |
1128 | git clone --bare . bare && | |
1129 | { | |
8125a58b | 1130 | echo $ZERO_OID $(git --git-dir=bare rev-parse HEAD) 1 && |
a4bf1e3c ES |
1131 | echo $(pwd)/bare/worktrees/goozy && |
1132 | echo $(pwd)/goozy | |
1133 | } >hook.expect && | |
1134 | post_checkout_hook bare && | |
1135 | git -C bare worktree add --detach ../goozy && | |
1136 | test_cmp hook.expect goozy/hook.actual | |
ade546be ES |
1137 | ' |
1138 | ||
cb56f55c ES |
1139 | test_expect_success '"add" an existing but missing worktree' ' |
1140 | git worktree add --detach pneu && | |
1141 | test_must_fail git worktree add --detach pneu && | |
1142 | rm -fr pneu && | |
e19831c9 ES |
1143 | test_must_fail git worktree add --detach pneu && |
1144 | git worktree add --force --detach pneu | |
1145 | ' | |
1146 | ||
1147 | test_expect_success '"add" an existing locked but missing worktree' ' | |
1148 | git worktree add --detach gnoo && | |
1149 | git worktree lock gnoo && | |
1150 | test_when_finished "git worktree unlock gnoo || :" && | |
1151 | rm -fr gnoo && | |
1152 | test_must_fail git worktree add --detach gnoo && | |
1153 | test_must_fail git worktree add --force --detach gnoo && | |
1154 | git worktree add --force --force --detach gnoo | |
cb56f55c ES |
1155 | ' |
1156 | ||
bb69b3b0 ES |
1157 | test_expect_success '"add" not tripped up by magic worktree matching"' ' |
1158 | # if worktree "sub1/bar" exists, "git worktree add bar" in distinct | |
1159 | # directory `sub2` should not mistakenly complain that `bar` is an | |
1160 | # already-registered worktree | |
1161 | mkdir sub1 sub2 && | |
1162 | git -C sub1 --git-dir=../.git worktree add --detach bozo && | |
1163 | git -C sub2 --git-dir=../.git worktree add --detach bozo | |
1164 | ' | |
1165 | ||
1de16aec NTND |
1166 | test_expect_success FUNNYNAMES 'sanitize generated worktree name' ' |
1167 | git worktree add --detach ". weird*..?.lock.lock" && | |
1168 | test -d .git/worktrees/---weird-.- | |
1169 | ' | |
1170 | ||
105df73e NTND |
1171 | test_expect_success '"add" should not fail because of another bad worktree' ' |
1172 | git init add-fail && | |
1173 | ( | |
1174 | cd add-fail && | |
1175 | test_commit first && | |
1176 | mkdir sub && | |
1177 | git worktree add sub/to-be-deleted && | |
1178 | rm -rf sub && | |
1179 | git worktree add second | |
1180 | ) | |
1181 | ' | |
1182 | ||
4782cf2a | 1183 | test_expect_success '"add" with uninitialized submodule, with submodule.recurse unset' ' |
99f4abb8 | 1184 | test_config_global protocol.file.allow always && |
4782cf2a PB |
1185 | test_create_repo submodule && |
1186 | test_commit -C submodule first && | |
1187 | test_create_repo project && | |
1188 | git -C project submodule add ../submodule && | |
1189 | git -C project add submodule && | |
1190 | test_tick && | |
1191 | git -C project commit -m add_sub && | |
1192 | git clone project project-clone && | |
1193 | git -C project-clone worktree add ../project-2 | |
1194 | ' | |
1195 | test_expect_success '"add" with uninitialized submodule, with submodule.recurse set' ' | |
1196 | git -C project-clone -c submodule.recurse worktree add ../project-3 | |
1197 | ' | |
1198 | ||
1199 | test_expect_success '"add" with initialized submodule, with submodule.recurse unset' ' | |
99f4abb8 | 1200 | test_config_global protocol.file.allow always && |
4782cf2a PB |
1201 | git -C project-clone submodule update --init && |
1202 | git -C project-clone worktree add ../project-4 | |
1203 | ' | |
1204 | ||
1205 | test_expect_success '"add" with initialized submodule, with submodule.recurse set' ' | |
1206 | git -C project-clone -c submodule.recurse worktree add ../project-5 | |
1207 | ' | |
1208 | ||
529fef20 | 1209 | test_done |