]>
Commit | Line | Data |
---|---|---|
1 | #!/bin/sh | |
2 | ||
3 | test_description=clone | |
4 | ||
5 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main | |
6 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME | |
7 | ||
8 | . ./test-lib.sh | |
9 | ||
10 | X= | |
11 | test_have_prereq !MINGW || X=.exe | |
12 | ||
13 | test_expect_success setup ' | |
14 | ||
15 | rm -fr .git && | |
16 | test_create_repo src && | |
17 | ( | |
18 | cd src && | |
19 | >file && | |
20 | git add file && | |
21 | git commit -m initial && | |
22 | echo 1 >file && | |
23 | git add file && | |
24 | git commit -m updated | |
25 | ) | |
26 | ||
27 | ' | |
28 | ||
29 | test_expect_success 'clone with excess parameters (1)' ' | |
30 | ||
31 | rm -fr dst && | |
32 | test_must_fail git clone -n src dst junk | |
33 | ||
34 | ' | |
35 | ||
36 | test_expect_success 'clone with excess parameters (2)' ' | |
37 | ||
38 | rm -fr dst && | |
39 | test_must_fail git clone -n "file://$(pwd)/src" dst junk | |
40 | ||
41 | ' | |
42 | ||
43 | test_expect_success 'output from clone' ' | |
44 | rm -fr dst && | |
45 | git clone -n "file://$(pwd)/src" dst >output 2>&1 && | |
46 | test $(grep Clon output | wc -l) = 1 | |
47 | ' | |
48 | ||
49 | test_expect_success 'clone does not keep pack' ' | |
50 | ||
51 | rm -fr dst && | |
52 | git clone -n "file://$(pwd)/src" dst && | |
53 | ! test -f dst/file && | |
54 | ! (echo dst/.git/objects/pack/pack-* | grep "\.keep") | |
55 | ||
56 | ' | |
57 | ||
58 | test_expect_success 'clone checks out files' ' | |
59 | ||
60 | rm -fr dst && | |
61 | git clone src dst && | |
62 | test -f dst/file | |
63 | ||
64 | ' | |
65 | ||
66 | test_expect_success 'clone respects GIT_WORK_TREE' ' | |
67 | ||
68 | GIT_WORK_TREE=worktree git clone src bare && | |
69 | test -f bare/config && | |
70 | test -f worktree/file | |
71 | ||
72 | ' | |
73 | ||
74 | test_expect_success 'clone from hooks' ' | |
75 | ||
76 | test_create_repo r0 && | |
77 | cd r0 && | |
78 | test_commit initial && | |
79 | cd .. && | |
80 | git init r1 && | |
81 | cd r1 && | |
82 | cat >.git/hooks/pre-commit <<-\EOF && | |
83 | #!/bin/sh | |
84 | git clone ../r0 ../r2 | |
85 | exit 1 | |
86 | EOF | |
87 | chmod u+x .git/hooks/pre-commit && | |
88 | : >file && | |
89 | git add file && | |
90 | test_must_fail git commit -m invoke-hook && | |
91 | cd .. && | |
92 | test_cmp r0/.git/HEAD r2/.git/HEAD && | |
93 | test_cmp r0/initial.t r2/initial.t | |
94 | ||
95 | ' | |
96 | ||
97 | test_expect_success 'clone creates intermediate directories' ' | |
98 | ||
99 | git clone src long/path/to/dst && | |
100 | test -f long/path/to/dst/file | |
101 | ||
102 | ' | |
103 | ||
104 | test_expect_success 'clone creates intermediate directories for bare repo' ' | |
105 | ||
106 | git clone --bare src long/path/to/bare/dst && | |
107 | test -f long/path/to/bare/dst/config | |
108 | ||
109 | ' | |
110 | ||
111 | test_expect_success 'clone --mirror' ' | |
112 | ||
113 | git clone --mirror src mirror && | |
114 | test -f mirror/HEAD && | |
115 | test ! -f mirror/file && | |
116 | FETCH="$(cd mirror && git config remote.origin.fetch)" && | |
117 | test "+refs/*:refs/*" = "$FETCH" && | |
118 | MIRROR="$(cd mirror && git config --bool remote.origin.mirror)" && | |
119 | test "$MIRROR" = true | |
120 | ||
121 | ' | |
122 | ||
123 | test_expect_success 'clone --mirror with detached HEAD' ' | |
124 | ||
125 | ( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) && | |
126 | git clone --mirror src mirror.detached && | |
127 | ( cd src && git checkout - ) && | |
128 | GIT_DIR=mirror.detached git rev-parse HEAD >actual && | |
129 | test_cmp expected actual | |
130 | ||
131 | ' | |
132 | ||
133 | test_expect_success 'clone --bare with detached HEAD' ' | |
134 | ||
135 | ( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) && | |
136 | git clone --bare src bare.detached && | |
137 | ( cd src && git checkout - ) && | |
138 | GIT_DIR=bare.detached git rev-parse HEAD >actual && | |
139 | test_cmp expected actual | |
140 | ||
141 | ' | |
142 | ||
143 | test_expect_success 'clone --bare names the local repository <name>.git' ' | |
144 | ||
145 | git clone --bare src && | |
146 | test -d src.git | |
147 | ||
148 | ' | |
149 | ||
150 | test_expect_success 'clone --mirror does not repeat tags' ' | |
151 | ||
152 | (cd src && | |
153 | git tag some-tag HEAD) && | |
154 | git clone --mirror src mirror2 && | |
155 | (cd mirror2 && | |
156 | git show-ref 2> clone.err > clone.out) && | |
157 | ! grep Duplicate mirror2/clone.err && | |
158 | grep some-tag mirror2/clone.out | |
159 | ||
160 | ' | |
161 | ||
162 | test_expect_success 'clone to destination with trailing /' ' | |
163 | ||
164 | git clone src target-1/ && | |
165 | T=$( cd target-1 && git rev-parse HEAD ) && | |
166 | S=$( cd src && git rev-parse HEAD ) && | |
167 | test "$T" = "$S" | |
168 | ||
169 | ' | |
170 | ||
171 | test_expect_success 'clone to destination with extra trailing /' ' | |
172 | ||
173 | git clone src target-2/// && | |
174 | T=$( cd target-2 && git rev-parse HEAD ) && | |
175 | S=$( cd src && git rev-parse HEAD ) && | |
176 | test "$T" = "$S" | |
177 | ||
178 | ' | |
179 | ||
180 | test_expect_success 'clone to an existing empty directory' ' | |
181 | mkdir target-3 && | |
182 | git clone src target-3 && | |
183 | T=$( cd target-3 && git rev-parse HEAD ) && | |
184 | S=$( cd src && git rev-parse HEAD ) && | |
185 | test "$T" = "$S" | |
186 | ' | |
187 | ||
188 | test_expect_success 'clone to an existing non-empty directory' ' | |
189 | mkdir target-4 && | |
190 | >target-4/Fakefile && | |
191 | test_must_fail git clone src target-4 | |
192 | ' | |
193 | ||
194 | test_expect_success 'clone to an existing path' ' | |
195 | >target-5 && | |
196 | test_must_fail git clone src target-5 | |
197 | ' | |
198 | ||
199 | test_expect_success 'clone a void' ' | |
200 | mkdir src-0 && | |
201 | ( | |
202 | cd src-0 && git init | |
203 | ) && | |
204 | git clone "file://$(pwd)/src-0" target-6 2>err-6 && | |
205 | ! grep "fatal:" err-6 && | |
206 | ( | |
207 | cd src-0 && test_commit A | |
208 | ) && | |
209 | git clone "file://$(pwd)/src-0" target-7 2>err-7 && | |
210 | ! grep "fatal:" err-7 && | |
211 | # There is no reason to insist they are bit-for-bit | |
212 | # identical, but this test should suffice for now. | |
213 | test_cmp target-6/.git/config target-7/.git/config | |
214 | ' | |
215 | ||
216 | test_expect_success 'clone respects global branch.autosetuprebase' ' | |
217 | ( | |
218 | test_config="$HOME/.gitconfig" && | |
219 | git config -f "$test_config" branch.autosetuprebase remote && | |
220 | rm -fr dst && | |
221 | git clone src dst && | |
222 | cd dst && | |
223 | actual="z$(git config branch.main.rebase)" && | |
224 | test ztrue = $actual | |
225 | ) | |
226 | ' | |
227 | ||
228 | test_expect_success 'respect url-encoding of file://' ' | |
229 | git init x+y && | |
230 | git clone "file://$PWD/x+y" xy-url-1 && | |
231 | git clone "file://$PWD/x%2By" xy-url-2 | |
232 | ' | |
233 | ||
234 | test_expect_success 'do not query-string-decode + in URLs' ' | |
235 | rm -rf x+y && | |
236 | git init "x y" && | |
237 | test_must_fail git clone "file://$PWD/x+y" xy-no-plus | |
238 | ' | |
239 | ||
240 | test_expect_success 'do not respect url-encoding of non-url path' ' | |
241 | git init x+y && | |
242 | test_must_fail git clone x%2By xy-regular && | |
243 | git clone x+y xy-regular | |
244 | ' | |
245 | ||
246 | test_expect_success 'clone separate gitdir' ' | |
247 | rm -rf dst && | |
248 | git clone --separate-git-dir realgitdir src dst && | |
249 | test -d realgitdir/refs | |
250 | ' | |
251 | ||
252 | test_expect_success 'clone separate gitdir: output' ' | |
253 | echo "gitdir: $(pwd)/realgitdir" >expected && | |
254 | test_cmp expected dst/.git | |
255 | ' | |
256 | ||
257 | test_expect_success 'clone from .git file' ' | |
258 | git clone dst/.git dst2 | |
259 | ' | |
260 | ||
261 | test_expect_success 'fetch from .git gitfile' ' | |
262 | ( | |
263 | cd dst2 && | |
264 | git fetch ../dst/.git | |
265 | ) | |
266 | ' | |
267 | ||
268 | test_expect_success 'fetch from gitfile parent' ' | |
269 | ( | |
270 | cd dst2 && | |
271 | git fetch ../dst | |
272 | ) | |
273 | ' | |
274 | ||
275 | test_expect_success 'clone separate gitdir where target already exists' ' | |
276 | rm -rf dst && | |
277 | echo foo=bar >>realgitdir/config && | |
278 | test_must_fail git clone --separate-git-dir realgitdir src dst && | |
279 | grep foo=bar realgitdir/config | |
280 | ' | |
281 | ||
282 | test_expect_success 'clone --reference from original' ' | |
283 | git clone --shared --bare src src-1 && | |
284 | git clone --bare src src-2 && | |
285 | git clone --reference=src-2 --bare src-1 target-8 && | |
286 | grep /src-2/ target-8/objects/info/alternates | |
287 | ' | |
288 | ||
289 | test_expect_success 'clone with more than one --reference' ' | |
290 | git clone --bare src src-3 && | |
291 | git clone --bare src src-4 && | |
292 | git clone --reference=src-3 --reference=src-4 src target-9 && | |
293 | grep /src-3/ target-9/.git/objects/info/alternates && | |
294 | grep /src-4/ target-9/.git/objects/info/alternates | |
295 | ' | |
296 | ||
297 | test_expect_success 'clone from original with relative alternate' ' | |
298 | mkdir nest && | |
299 | git clone --bare src nest/src-5 && | |
300 | echo ../../../src/.git/objects >nest/src-5/objects/info/alternates && | |
301 | git clone --bare nest/src-5 target-10 && | |
302 | grep /src/\\.git/objects target-10/objects/info/alternates | |
303 | ' | |
304 | ||
305 | test_expect_success 'clone checking out a tag' ' | |
306 | git clone --branch=some-tag src dst.tag && | |
307 | GIT_DIR=src/.git git rev-parse some-tag >expected && | |
308 | test_cmp expected dst.tag/.git/HEAD && | |
309 | GIT_DIR=dst.tag/.git git config remote.origin.fetch >fetch.actual && | |
310 | echo "+refs/heads/*:refs/remotes/origin/*" >fetch.expected && | |
311 | test_cmp fetch.expected fetch.actual | |
312 | ' | |
313 | ||
314 | test_expect_success 'set up ssh wrapper' ' | |
315 | cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" \ | |
316 | "$TRASH_DIRECTORY/ssh$X" && | |
317 | GIT_SSH="$TRASH_DIRECTORY/ssh$X" && | |
318 | export GIT_SSH && | |
319 | export TRASH_DIRECTORY && | |
320 | >"$TRASH_DIRECTORY"/ssh-output | |
321 | ' | |
322 | ||
323 | copy_ssh_wrapper_as () { | |
324 | rm -f "${1%$X}$X" && | |
325 | cp "$TRASH_DIRECTORY/ssh$X" "${1%$X}$X" && | |
326 | test_when_finished "rm $(git rev-parse --sq-quote "${1%$X}$X")" && | |
327 | GIT_SSH="${1%$X}$X" && | |
328 | test_when_finished "GIT_SSH=\"\$TRASH_DIRECTORY/ssh\$X\"" | |
329 | } | |
330 | ||
331 | expect_ssh () { | |
332 | test_when_finished ' | |
333 | (cd "$TRASH_DIRECTORY" && rm -f ssh-expect && >ssh-output) | |
334 | ' && | |
335 | { | |
336 | case "$#" in | |
337 | 1) | |
338 | ;; | |
339 | 2) | |
340 | echo "ssh: $1 git-upload-pack '$2'" | |
341 | ;; | |
342 | 3) | |
343 | echo "ssh: $1 $2 git-upload-pack '$3'" | |
344 | ;; | |
345 | *) | |
346 | echo "ssh: $1 $2 git-upload-pack '$3' $4" | |
347 | esac | |
348 | } >"$TRASH_DIRECTORY/ssh-expect" && | |
349 | (cd "$TRASH_DIRECTORY" && test_cmp ssh-expect ssh-output) | |
350 | } | |
351 | ||
352 | test_expect_success 'clone myhost:src uses ssh' ' | |
353 | GIT_TEST_PROTOCOL_VERSION=0 git clone myhost:src ssh-clone && | |
354 | expect_ssh myhost src | |
355 | ' | |
356 | ||
357 | test_expect_success !MINGW,!CYGWIN 'clone local path foo:bar' ' | |
358 | cp -R src "foo:bar" && | |
359 | git clone "foo:bar" foobar && | |
360 | expect_ssh none | |
361 | ' | |
362 | ||
363 | test_expect_success 'bracketed hostnames are still ssh' ' | |
364 | GIT_TEST_PROTOCOL_VERSION=0 git clone "[myhost:123]:src" ssh-bracket-clone && | |
365 | expect_ssh "-p 123" myhost src | |
366 | ' | |
367 | ||
368 | test_expect_success 'OpenSSH variant passes -4' ' | |
369 | GIT_TEST_PROTOCOL_VERSION=0 git clone -4 "[myhost:123]:src" ssh-ipv4-clone && | |
370 | expect_ssh "-4 -p 123" myhost src | |
371 | ' | |
372 | ||
373 | test_expect_success 'variant can be overridden' ' | |
374 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/putty" && | |
375 | git -c ssh.variant=putty clone -4 "[myhost:123]:src" ssh-putty-clone && | |
376 | expect_ssh "-4 -P 123" myhost src | |
377 | ' | |
378 | ||
379 | test_expect_success 'variant=auto picks based on basename' ' | |
380 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && | |
381 | git -c ssh.variant=auto clone -4 "[myhost:123]:src" ssh-auto-clone && | |
382 | expect_ssh "-4 -P 123" myhost src | |
383 | ' | |
384 | ||
385 | test_expect_success 'simple does not support -4/-6' ' | |
386 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/simple" && | |
387 | test_must_fail git clone -4 "myhost:src" ssh-4-clone-simple | |
388 | ' | |
389 | ||
390 | test_expect_success 'simple does not support port' ' | |
391 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/simple" && | |
392 | test_must_fail git clone "[myhost:123]:src" ssh-bracket-clone-simple | |
393 | ' | |
394 | ||
395 | test_expect_success 'uplink is treated as simple' ' | |
396 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/uplink" && | |
397 | test_must_fail git clone "[myhost:123]:src" ssh-bracket-clone-uplink && | |
398 | git clone "myhost:src" ssh-clone-uplink && | |
399 | expect_ssh myhost src | |
400 | ' | |
401 | ||
402 | test_expect_success 'OpenSSH-like uplink is treated as ssh' ' | |
403 | write_script "$TRASH_DIRECTORY/uplink" <<-EOF && | |
404 | if test "\$1" = "-G" | |
405 | then | |
406 | exit 0 | |
407 | fi && | |
408 | exec "\$TRASH_DIRECTORY/ssh$X" "\$@" | |
409 | EOF | |
410 | test_when_finished "rm -f \"\$TRASH_DIRECTORY/uplink\"" && | |
411 | GIT_SSH="$TRASH_DIRECTORY/uplink" && | |
412 | test_when_finished "GIT_SSH=\"\$TRASH_DIRECTORY/ssh\$X\"" && | |
413 | GIT_TEST_PROTOCOL_VERSION=0 git clone "[myhost:123]:src" ssh-bracket-clone-sshlike-uplink && | |
414 | expect_ssh "-p 123" myhost src | |
415 | ' | |
416 | ||
417 | test_expect_success 'plink is treated specially (as putty)' ' | |
418 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && | |
419 | git clone "[myhost:123]:src" ssh-bracket-clone-plink-0 && | |
420 | expect_ssh "-P 123" myhost src | |
421 | ' | |
422 | ||
423 | test_expect_success 'plink.exe is treated specially (as putty)' ' | |
424 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" && | |
425 | git clone "[myhost:123]:src" ssh-bracket-clone-plink-1 && | |
426 | expect_ssh "-P 123" myhost src | |
427 | ' | |
428 | ||
429 | test_expect_success 'tortoiseplink is like putty, with extra arguments' ' | |
430 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/tortoiseplink" && | |
431 | git clone "[myhost:123]:src" ssh-bracket-clone-plink-2 && | |
432 | expect_ssh "-batch -P 123" myhost src | |
433 | ' | |
434 | ||
435 | test_expect_success 'double quoted plink.exe in GIT_SSH_COMMAND' ' | |
436 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" && | |
437 | GIT_SSH_COMMAND="\"$TRASH_DIRECTORY/plink.exe\" -v" \ | |
438 | git clone "[myhost:123]:src" ssh-bracket-clone-plink-3 && | |
439 | expect_ssh "-v -P 123" myhost src | |
440 | ' | |
441 | ||
442 | test_expect_success 'single quoted plink.exe in GIT_SSH_COMMAND' ' | |
443 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" && | |
444 | GIT_SSH_COMMAND="$SQ$TRASH_DIRECTORY/plink.exe$SQ -v" \ | |
445 | git clone "[myhost:123]:src" ssh-bracket-clone-plink-4 && | |
446 | expect_ssh "-v -P 123" myhost src | |
447 | ' | |
448 | ||
449 | test_expect_success 'GIT_SSH_VARIANT overrides plink detection' ' | |
450 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && | |
451 | GIT_TEST_PROTOCOL_VERSION=0 GIT_SSH_VARIANT=ssh \ | |
452 | git clone "[myhost:123]:src" ssh-bracket-clone-variant-1 && | |
453 | expect_ssh "-p 123" myhost src | |
454 | ' | |
455 | ||
456 | test_expect_success 'ssh.variant overrides plink detection' ' | |
457 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && | |
458 | GIT_TEST_PROTOCOL_VERSION=0 git -c ssh.variant=ssh \ | |
459 | clone "[myhost:123]:src" ssh-bracket-clone-variant-2 && | |
460 | expect_ssh "-p 123" myhost src | |
461 | ' | |
462 | ||
463 | test_expect_success 'GIT_SSH_VARIANT overrides plink detection to plink' ' | |
464 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && | |
465 | GIT_SSH_VARIANT=plink \ | |
466 | git clone "[myhost:123]:src" ssh-bracket-clone-variant-3 && | |
467 | expect_ssh "-P 123" myhost src | |
468 | ' | |
469 | ||
470 | test_expect_success 'GIT_SSH_VARIANT overrides plink to tortoiseplink' ' | |
471 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && | |
472 | GIT_SSH_VARIANT=tortoiseplink \ | |
473 | git clone "[myhost:123]:src" ssh-bracket-clone-variant-4 && | |
474 | expect_ssh "-batch -P 123" myhost src | |
475 | ' | |
476 | ||
477 | test_expect_success 'clean failure on broken quoting' ' | |
478 | test_must_fail \ | |
479 | env GIT_SSH_COMMAND="${SQ}plink.exe -v" \ | |
480 | git clone "[myhost:123]:src" sq-failure | |
481 | ' | |
482 | ||
483 | counter=0 | |
484 | # $1 url | |
485 | # $2 none|host | |
486 | # $3 path | |
487 | test_clone_url () { | |
488 | counter=$(($counter + 1)) | |
489 | test_might_fail env GIT_TEST_PROTOCOL_VERSION=0 git clone "$1" tmp$counter && | |
490 | shift && | |
491 | expect_ssh "$@" | |
492 | } | |
493 | ||
494 | test_expect_success !MINGW,!CYGWIN 'clone c:temp is ssl' ' | |
495 | test_clone_url c:temp c temp | |
496 | ' | |
497 | ||
498 | test_expect_success MINGW 'clone c:temp is dos drive' ' | |
499 | test_clone_url c:temp none | |
500 | ' | |
501 | ||
502 | #ip v4 | |
503 | for repo in rep rep/home/project 123 | |
504 | do | |
505 | test_expect_success "clone host:$repo" ' | |
506 | test_clone_url host:$repo host $repo | |
507 | ' | |
508 | done | |
509 | ||
510 | #ipv6 | |
511 | for repo in rep rep/home/project 123 | |
512 | do | |
513 | test_expect_success "clone [::1]:$repo" ' | |
514 | test_clone_url [::1]:$repo ::1 "$repo" | |
515 | ' | |
516 | done | |
517 | #home directory | |
518 | test_expect_success "clone host:/~repo" ' | |
519 | test_clone_url host:/~repo host "~repo" | |
520 | ' | |
521 | ||
522 | test_expect_success "clone [::1]:/~repo" ' | |
523 | test_clone_url [::1]:/~repo ::1 "~repo" | |
524 | ' | |
525 | ||
526 | # Corner cases | |
527 | for url in foo/bar:baz [foo]bar/baz:qux [foo/bar]:baz | |
528 | do | |
529 | test_expect_success "clone $url is not ssh" ' | |
530 | test_clone_url $url none | |
531 | ' | |
532 | done | |
533 | ||
534 | #with ssh:// scheme | |
535 | #ignore trailing colon | |
536 | for tcol in "" : | |
537 | do | |
538 | test_expect_success "clone ssh://host.xz$tcol/home/user/repo" ' | |
539 | test_clone_url "ssh://host.xz$tcol/home/user/repo" host.xz /home/user/repo | |
540 | ' | |
541 | # from home directory | |
542 | test_expect_success "clone ssh://host.xz$tcol/~repo" ' | |
543 | test_clone_url "ssh://host.xz$tcol/~repo" host.xz "~repo" | |
544 | ' | |
545 | done | |
546 | ||
547 | # with port number | |
548 | test_expect_success 'clone ssh://host.xz:22/home/user/repo' ' | |
549 | test_clone_url "ssh://host.xz:22/home/user/repo" "-p 22 host.xz" "/home/user/repo" | |
550 | ' | |
551 | ||
552 | # from home directory with port number | |
553 | test_expect_success 'clone ssh://host.xz:22/~repo' ' | |
554 | test_clone_url "ssh://host.xz:22/~repo" "-p 22 host.xz" "~repo" | |
555 | ' | |
556 | ||
557 | #IPv6 | |
558 | for tuah in ::1 [::1] [::1]: user@::1 user@[::1] user@[::1]: [user@::1] [user@::1]: | |
559 | do | |
560 | ehost=$(echo $tuah | sed -e "s/1]:/1]/" | tr -d "[]") | |
561 | test_expect_success "clone ssh://$tuah/home/user/repo" " | |
562 | test_clone_url ssh://$tuah/home/user/repo $ehost /home/user/repo | |
563 | " | |
564 | done | |
565 | ||
566 | #IPv6 from home directory | |
567 | for tuah in ::1 [::1] user@::1 user@[::1] [user@::1] | |
568 | do | |
569 | euah=$(echo $tuah | tr -d "[]") | |
570 | test_expect_success "clone ssh://$tuah/~repo" " | |
571 | test_clone_url ssh://$tuah/~repo $euah '~repo' | |
572 | " | |
573 | done | |
574 | ||
575 | #IPv6 with port number | |
576 | for tuah in [::1] user@[::1] [user@::1] | |
577 | do | |
578 | euah=$(echo $tuah | tr -d "[]") | |
579 | test_expect_success "clone ssh://$tuah:22/home/user/repo" " | |
580 | test_clone_url ssh://$tuah:22/home/user/repo '-p 22' $euah /home/user/repo | |
581 | " | |
582 | done | |
583 | ||
584 | #IPv6 from home directory with port number | |
585 | for tuah in [::1] user@[::1] [user@::1] | |
586 | do | |
587 | euah=$(echo $tuah | tr -d "[]") | |
588 | test_expect_success "clone ssh://$tuah:22/~repo" " | |
589 | test_clone_url ssh://$tuah:22/~repo '-p 22' $euah '~repo' | |
590 | " | |
591 | done | |
592 | ||
593 | test_expect_success 'clone from a repository with two identical branches' ' | |
594 | ||
595 | ( | |
596 | cd src && | |
597 | git checkout -b another main | |
598 | ) && | |
599 | git clone src target-11 && | |
600 | test "z$( cd target-11 && git symbolic-ref HEAD )" = zrefs/heads/another | |
601 | ||
602 | ' | |
603 | ||
604 | test_expect_success 'shallow clone locally' ' | |
605 | git clone --depth=1 --no-local src ssrrcc && | |
606 | git clone ssrrcc ddsstt && | |
607 | test_cmp ssrrcc/.git/shallow ddsstt/.git/shallow && | |
608 | ( cd ddsstt && git fsck ) | |
609 | ' | |
610 | ||
611 | test_expect_success 'GIT_TRACE_PACKFILE produces a usable pack' ' | |
612 | rm -rf dst.git && | |
613 | GIT_TRACE_PACKFILE=$PWD/tmp.pack git clone --no-local --bare src dst.git && | |
614 | git init --bare replay.git && | |
615 | git -C replay.git index-pack -v --stdin <tmp.pack | |
616 | ' | |
617 | ||
618 | test_expect_success 'clone on case-insensitive fs' ' | |
619 | git init icasefs && | |
620 | ( | |
621 | cd icasefs && | |
622 | o=$(git hash-object -w --stdin </dev/null | hex2oct) && | |
623 | t=$(printf "100644 X\0${o}100644 x\0${o}" | | |
624 | git hash-object -w -t tree --stdin) && | |
625 | c=$(git commit-tree -m bogus $t) && | |
626 | git update-ref refs/heads/bogus $c && | |
627 | git clone -b bogus . bogus 2>warning | |
628 | ) | |
629 | ' | |
630 | ||
631 | test_expect_success CASE_INSENSITIVE_FS 'colliding file detection' ' | |
632 | grep X icasefs/warning && | |
633 | grep x icasefs/warning && | |
634 | test_i18ngrep "the following paths have collided" icasefs/warning | |
635 | ' | |
636 | ||
637 | test_expect_success 'clone with GIT_DEFAULT_HASH' ' | |
638 | ( | |
639 | sane_unset GIT_DEFAULT_HASH && | |
640 | git init --object-format=sha1 test-sha1 && | |
641 | git init --object-format=sha256 test-sha256 | |
642 | ) && | |
643 | test_commit -C test-sha1 foo && | |
644 | test_commit -C test-sha256 foo && | |
645 | GIT_DEFAULT_HASH=sha1 git clone test-sha256 test-clone-sha256 && | |
646 | GIT_DEFAULT_HASH=sha256 git clone test-sha1 test-clone-sha1 && | |
647 | git -C test-clone-sha1 status && | |
648 | git -C test-clone-sha256 status | |
649 | ' | |
650 | ||
651 | partial_clone_server () { | |
652 | SERVER="$1" && | |
653 | ||
654 | rm -rf "$SERVER" client && | |
655 | test_create_repo "$SERVER" && | |
656 | test_commit -C "$SERVER" one && | |
657 | HASH1=$(git -C "$SERVER" hash-object one.t) && | |
658 | git -C "$SERVER" revert HEAD && | |
659 | test_commit -C "$SERVER" two && | |
660 | HASH2=$(git -C "$SERVER" hash-object two.t) && | |
661 | test_config -C "$SERVER" uploadpack.allowfilter 1 && | |
662 | test_config -C "$SERVER" uploadpack.allowanysha1inwant 1 | |
663 | } | |
664 | ||
665 | partial_clone () { | |
666 | SERVER="$1" && | |
667 | URL="$2" && | |
668 | ||
669 | partial_clone_server "${SERVER}" && | |
670 | git clone --filter=blob:limit=0 "$URL" client && | |
671 | ||
672 | git -C client fsck && | |
673 | ||
674 | # Ensure that unneeded blobs are not inadvertently fetched. | |
675 | test_config -C client remote.origin.promisor "false" && | |
676 | git -C client config --unset remote.origin.partialclonefilter && | |
677 | test_must_fail git -C client cat-file -e "$HASH1" && | |
678 | ||
679 | # But this blob was fetched, because clone performs an initial checkout | |
680 | git -C client cat-file -e "$HASH2" | |
681 | } | |
682 | ||
683 | test_expect_success 'partial clone' ' | |
684 | partial_clone server "file://$(pwd)/server" | |
685 | ' | |
686 | ||
687 | test_expect_success 'partial clone with -o' ' | |
688 | partial_clone_server server && | |
689 | git clone -o blah --filter=blob:limit=0 "file://$(pwd)/server" client && | |
690 | test_cmp_config -C client "blob:limit=0" --get-all remote.blah.partialclonefilter | |
691 | ' | |
692 | ||
693 | test_expect_success 'partial clone: warn if server does not support object filtering' ' | |
694 | rm -rf server client && | |
695 | test_create_repo server && | |
696 | test_commit -C server one && | |
697 | ||
698 | git clone --filter=blob:limit=0 "file://$(pwd)/server" client 2> err && | |
699 | ||
700 | test_i18ngrep "filtering not recognized by server" err | |
701 | ' | |
702 | ||
703 | test_expect_success 'batch missing blob request during checkout' ' | |
704 | rm -rf server client && | |
705 | ||
706 | test_create_repo server && | |
707 | echo a >server/a && | |
708 | echo b >server/b && | |
709 | git -C server add a b && | |
710 | ||
711 | git -C server commit -m x && | |
712 | echo aa >server/a && | |
713 | echo bb >server/b && | |
714 | git -C server add a b && | |
715 | git -C server commit -m x && | |
716 | ||
717 | test_config -C server uploadpack.allowfilter 1 && | |
718 | test_config -C server uploadpack.allowanysha1inwant 1 && | |
719 | ||
720 | git clone --filter=blob:limit=0 "file://$(pwd)/server" client && | |
721 | ||
722 | # Ensure that there is only one negotiation by checking that there is | |
723 | # only "done" line sent. ("done" marks the end of negotiation.) | |
724 | GIT_TRACE_PACKET="$(pwd)/trace" git -C client checkout HEAD^ && | |
725 | grep "fetch> done" trace >done_lines && | |
726 | test_line_count = 1 done_lines | |
727 | ' | |
728 | ||
729 | test_expect_success 'batch missing blob request does not inadvertently try to fetch gitlinks' ' | |
730 | rm -rf server client && | |
731 | ||
732 | test_create_repo repo_for_submodule && | |
733 | test_commit -C repo_for_submodule x && | |
734 | ||
735 | test_create_repo server && | |
736 | echo a >server/a && | |
737 | echo b >server/b && | |
738 | git -C server add a b && | |
739 | git -C server commit -m x && | |
740 | ||
741 | echo aa >server/a && | |
742 | echo bb >server/b && | |
743 | # Also add a gitlink pointing to an arbitrary repository | |
744 | git -C server submodule add "$(pwd)/repo_for_submodule" c && | |
745 | git -C server add a b c && | |
746 | git -C server commit -m x && | |
747 | ||
748 | test_config -C server uploadpack.allowfilter 1 && | |
749 | test_config -C server uploadpack.allowanysha1inwant 1 && | |
750 | ||
751 | # Make sure that it succeeds | |
752 | git clone --filter=blob:limit=0 "file://$(pwd)/server" client | |
753 | ' | |
754 | ||
755 | . "$TEST_DIRECTORY"/lib-httpd.sh | |
756 | start_httpd | |
757 | ||
758 | test_expect_success 'partial clone using HTTP' ' | |
759 | partial_clone "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server" | |
760 | ' | |
761 | ||
762 | # DO NOT add non-httpd-specific tests here, because the last part of this | |
763 | # test script is only executed when httpd is available and enabled. | |
764 | ||
765 | test_done |