]>
Commit | Line | Data |
---|---|---|
a2b26acd JH |
1 | #!/bin/sh |
2 | ||
3 | test_description=clone | |
4 | ||
95cf2c01 | 5 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
334afbc7 JS |
6 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
7 | ||
a2b26acd JH |
8 | . ./test-lib.sh |
9 | ||
3064d5a3 JS |
10 | X= |
11 | test_have_prereq !MINGW || X=.exe | |
12 | ||
a2b26acd JH |
13 | test_expect_success setup ' |
14 | ||
15 | rm -fr .git && | |
16 | test_create_repo src && | |
17 | ( | |
bafe7631 NTND |
18 | cd src && |
19 | >file && | |
20 | git add file && | |
7f08c685 NTND |
21 | git commit -m initial && |
22 | echo 1 >file && | |
23 | git add file && | |
24 | git commit -m updated | |
a2b26acd JH |
25 | ) |
26 | ||
27 | ' | |
28 | ||
1db4a75c | 29 | test_expect_success 'clone with excess parameters (1)' ' |
a2b26acd | 30 | |
1db4a75c SP |
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 && | |
a2b26acd JH |
39 | test_must_fail git clone -n "file://$(pwd)/src" dst junk |
40 | ||
41 | ' | |
42 | ||
a926c4b9 | 43 | test_expect_success 'output from clone' ' |
2c3766f0 | 44 | rm -fr dst && |
68b939b2 | 45 | git clone -n "file://$(pwd)/src" dst >output 2>&1 && |
28ba96ab | 46 | test $(grep Clon output | wc -l) = 1 |
2c3766f0 AM |
47 | ' |
48 | ||
1db4a75c SP |
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 | ||
a73bc127 JS |
58 | test_expect_success 'clone checks out files' ' |
59 | ||
1db4a75c | 60 | rm -fr dst && |
a73bc127 JS |
61 | git clone src dst && |
62 | test -f dst/file | |
63 | ||
64 | ' | |
65 | ||
2beebd22 JK |
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 | ||
86d26f24 NTND |
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 && | |
60a8a6bf | 82 | test_hook pre-commit <<-\EOF && |
86d26f24 NTND |
83 | git clone ../r0 ../r2 |
84 | exit 1 | |
85 | EOF | |
86d26f24 NTND |
86 | : >file && |
87 | git add file && | |
88 | test_must_fail git commit -m invoke-hook && | |
89 | cd .. && | |
90 | test_cmp r0/.git/HEAD r2/.git/HEAD && | |
91 | test_cmp r0/initial.t r2/initial.t | |
92 | ||
93 | ' | |
94 | ||
2beebd22 JK |
95 | test_expect_success 'clone creates intermediate directories' ' |
96 | ||
97 | git clone src long/path/to/dst && | |
98 | test -f long/path/to/dst/file | |
99 | ||
100 | ' | |
101 | ||
102 | test_expect_success 'clone creates intermediate directories for bare repo' ' | |
103 | ||
104 | git clone --bare src long/path/to/bare/dst && | |
105 | test -f long/path/to/bare/dst/config | |
106 | ||
107 | ' | |
108 | ||
bc699afc JS |
109 | test_expect_success 'clone --mirror' ' |
110 | ||
111 | git clone --mirror src mirror && | |
112 | test -f mirror/HEAD && | |
113 | test ! -f mirror/file && | |
114 | FETCH="$(cd mirror && git config remote.origin.fetch)" && | |
115 | test "+refs/*:refs/*" = "$FETCH" && | |
116 | MIRROR="$(cd mirror && git config --bool remote.origin.mirror)" && | |
117 | test "$MIRROR" = true | |
118 | ||
119 | ' | |
120 | ||
7f08c685 NTND |
121 | test_expect_success 'clone --mirror with detached HEAD' ' |
122 | ||
123 | ( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) && | |
124 | git clone --mirror src mirror.detached && | |
125 | ( cd src && git checkout - ) && | |
126 | GIT_DIR=mirror.detached git rev-parse HEAD >actual && | |
127 | test_cmp expected actual | |
128 | ||
129 | ' | |
130 | ||
131 | test_expect_success 'clone --bare with detached HEAD' ' | |
132 | ||
133 | ( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) && | |
134 | git clone --bare src bare.detached && | |
135 | ( cd src && git checkout - ) && | |
136 | GIT_DIR=bare.detached git rev-parse HEAD >actual && | |
137 | test_cmp expected actual | |
138 | ||
139 | ' | |
140 | ||
6612f877 JS |
141 | test_expect_success 'clone --bare names the local repository <name>.git' ' |
142 | ||
143 | git clone --bare src && | |
144 | test -d src.git | |
145 | ||
146 | ' | |
147 | ||
468386a9 JS |
148 | test_expect_success 'clone --mirror does not repeat tags' ' |
149 | ||
150 | (cd src && | |
151 | git tag some-tag HEAD) && | |
152 | git clone --mirror src mirror2 && | |
153 | (cd mirror2 && | |
154 | git show-ref 2> clone.err > clone.out) && | |
c7cf9566 | 155 | ! grep Duplicate mirror2/clone.err && |
468386a9 JS |
156 | grep some-tag mirror2/clone.out |
157 | ||
158 | ' | |
159 | ||
5ed860f5 PS |
160 | test_expect_success 'clone with files ref format' ' |
161 | test_when_finished "rm -rf ref-storage" && | |
162 | git clone --ref-format=files --mirror src ref-storage && | |
163 | echo files >expect && | |
164 | git -C ref-storage rev-parse --show-ref-format >actual && | |
165 | test_cmp expect actual | |
166 | ' | |
167 | ||
168 | test_expect_success 'clone with garbage ref format' ' | |
169 | cat >expect <<-EOF && | |
170 | fatal: unknown ref storage format ${SQ}garbage${SQ} | |
171 | EOF | |
172 | test_must_fail git clone --ref-format=garbage --mirror src ref-storage 2>err && | |
173 | test_cmp expect err && | |
174 | test_path_is_missing ref-storage | |
175 | ' | |
176 | ||
44a68fd5 CB |
177 | test_expect_success 'clone to destination with trailing /' ' |
178 | ||
179 | git clone src target-1/ && | |
180 | T=$( cd target-1 && git rev-parse HEAD ) && | |
181 | S=$( cd src && git rev-parse HEAD ) && | |
182 | test "$T" = "$S" | |
183 | ||
184 | ' | |
185 | ||
186 | test_expect_success 'clone to destination with extra trailing /' ' | |
187 | ||
188 | git clone src target-2/// && | |
189 | T=$( cd target-2 && git rev-parse HEAD ) && | |
190 | S=$( cd src && git rev-parse HEAD ) && | |
191 | test "$T" = "$S" | |
192 | ||
193 | ' | |
194 | ||
55892d23 AP |
195 | test_expect_success 'clone to an existing empty directory' ' |
196 | mkdir target-3 && | |
197 | git clone src target-3 && | |
198 | T=$( cd target-3 && git rev-parse HEAD ) && | |
199 | S=$( cd src && git rev-parse HEAD ) && | |
200 | test "$T" = "$S" | |
201 | ' | |
202 | ||
203 | test_expect_success 'clone to an existing non-empty directory' ' | |
204 | mkdir target-4 && | |
205 | >target-4/Fakefile && | |
206 | test_must_fail git clone src target-4 | |
207 | ' | |
208 | ||
209 | test_expect_success 'clone to an existing path' ' | |
210 | >target-5 && | |
211 | test_must_fail git clone src target-5 | |
212 | ' | |
213 | ||
5cd12b85 JH |
214 | test_expect_success 'clone a void' ' |
215 | mkdir src-0 && | |
216 | ( | |
217 | cd src-0 && git init | |
218 | ) && | |
12d49966 JK |
219 | git clone "file://$(pwd)/src-0" target-6 2>err-6 && |
220 | ! grep "fatal:" err-6 && | |
5cd12b85 JH |
221 | ( |
222 | cd src-0 && test_commit A | |
223 | ) && | |
12d49966 JK |
224 | git clone "file://$(pwd)/src-0" target-7 2>err-7 && |
225 | ! grep "fatal:" err-7 && | |
5cd12b85 JH |
226 | # There is no reason to insist they are bit-for-bit |
227 | # identical, but this test should suffice for now. | |
228 | test_cmp target-6/.git/config target-7/.git/config | |
229 | ' | |
230 | ||
a9f2c136 JH |
231 | test_expect_success 'clone respects global branch.autosetuprebase' ' |
232 | ( | |
a9f2c136 | 233 | test_config="$HOME/.gitconfig" && |
a9f2c136 JH |
234 | git config -f "$test_config" branch.autosetuprebase remote && |
235 | rm -fr dst && | |
236 | git clone src dst && | |
237 | cd dst && | |
95cf2c01 | 238 | actual="z$(git config branch.main.rebase)" && |
a9f2c136 JH |
239 | test ztrue = $actual |
240 | ) | |
241 | ' | |
242 | ||
9d2e9420 JK |
243 | test_expect_success 'respect url-encoding of file://' ' |
244 | git init x+y && | |
730220de TR |
245 | git clone "file://$PWD/x+y" xy-url-1 && |
246 | git clone "file://$PWD/x%2By" xy-url-2 | |
247 | ' | |
248 | ||
249 | test_expect_success 'do not query-string-decode + in URLs' ' | |
250 | rm -rf x+y && | |
251 | git init "x y" && | |
252 | test_must_fail git clone "file://$PWD/x+y" xy-no-plus | |
9d2e9420 JK |
253 | ' |
254 | ||
255 | test_expect_success 'do not respect url-encoding of non-url path' ' | |
256 | git init x+y && | |
257 | test_must_fail git clone x%2By xy-regular && | |
258 | git clone x+y xy-regular | |
259 | ' | |
260 | ||
b57fb80a NTND |
261 | test_expect_success 'clone separate gitdir' ' |
262 | rm -rf dst && | |
263 | git clone --separate-git-dir realgitdir src dst && | |
b57fb80a NTND |
264 | test -d realgitdir/refs |
265 | ' | |
266 | ||
33d56fa0 | 267 | test_expect_success 'clone separate gitdir: output' ' |
c723e50d | 268 | echo "gitdir: $(pwd)/realgitdir" >expected && |
2c050e01 ÆAB |
269 | test_cmp expected dst/.git |
270 | ' | |
271 | ||
9b0ebc72 NTND |
272 | test_expect_success 'clone from .git file' ' |
273 | git clone dst/.git dst2 | |
274 | ' | |
275 | ||
0c80fdb3 PH |
276 | test_expect_success 'fetch from .git gitfile' ' |
277 | ( | |
278 | cd dst2 && | |
279 | git fetch ../dst/.git | |
280 | ) | |
281 | ' | |
282 | ||
283 | test_expect_success 'fetch from gitfile parent' ' | |
284 | ( | |
285 | cd dst2 && | |
286 | git fetch ../dst | |
287 | ) | |
288 | ' | |
289 | ||
b57fb80a NTND |
290 | test_expect_success 'clone separate gitdir where target already exists' ' |
291 | rm -rf dst && | |
dfaa209a BW |
292 | echo foo=bar >>realgitdir/config && |
293 | test_must_fail git clone --separate-git-dir realgitdir src dst && | |
294 | grep foo=bar realgitdir/config | |
b57fb80a NTND |
295 | ' |
296 | ||
e6baf4a1 | 297 | test_expect_success 'clone --reference from original' ' |
dbc92b07 JH |
298 | git clone --shared --bare src src-1 && |
299 | git clone --bare src src-2 && | |
300 | git clone --reference=src-2 --bare src-1 target-8 && | |
301 | grep /src-2/ target-8/objects/info/alternates | |
302 | ' | |
303 | ||
304 | test_expect_success 'clone with more than one --reference' ' | |
305 | git clone --bare src src-3 && | |
306 | git clone --bare src src-4 && | |
307 | git clone --reference=src-3 --reference=src-4 src target-9 && | |
308 | grep /src-3/ target-9/.git/objects/info/alternates && | |
309 | grep /src-4/ target-9/.git/objects/info/alternates | |
310 | ' | |
311 | ||
e6baf4a1 JH |
312 | test_expect_success 'clone from original with relative alternate' ' |
313 | mkdir nest && | |
314 | git clone --bare src nest/src-5 && | |
315 | echo ../../../src/.git/objects >nest/src-5/objects/info/alternates && | |
316 | git clone --bare nest/src-5 target-10 && | |
317 | grep /src/\\.git/objects target-10/objects/info/alternates | |
318 | ' | |
319 | ||
5a7d5b68 NTND |
320 | test_expect_success 'clone checking out a tag' ' |
321 | git clone --branch=some-tag src dst.tag && | |
322 | GIT_DIR=src/.git git rev-parse some-tag >expected && | |
dd8468ef HWN |
323 | GIT_DIR=dst.tag/.git git rev-parse HEAD >actual && |
324 | test_cmp expected actual && | |
5a7d5b68 NTND |
325 | GIT_DIR=dst.tag/.git git config remote.origin.fetch >fetch.actual && |
326 | echo "+refs/heads/*:refs/remotes/origin/*" >fetch.expected && | |
327 | test_cmp fetch.expected fetch.actual | |
328 | ' | |
329 | ||
8339805b JN |
330 | test_expect_success 'set up ssh wrapper' ' |
331 | cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" \ | |
332 | "$TRASH_DIRECTORY/ssh$X" && | |
333 | GIT_SSH="$TRASH_DIRECTORY/ssh$X" && | |
334 | export GIT_SSH && | |
335 | export TRASH_DIRECTORY && | |
336 | >"$TRASH_DIRECTORY"/ssh-output | |
337 | ' | |
8d3d28f5 | 338 | |
baaf2337 | 339 | copy_ssh_wrapper_as () { |
cff48ccf | 340 | rm -f "${1%$X}$X" && |
94b8ae5a | 341 | cp "$TRASH_DIRECTORY/ssh$X" "${1%$X}$X" && |
8339805b | 342 | test_when_finished "rm $(git rev-parse --sq-quote "${1%$X}$X")" && |
3064d5a3 | 343 | GIT_SSH="${1%$X}$X" && |
8339805b | 344 | test_when_finished "GIT_SSH=\"\$TRASH_DIRECTORY/ssh\$X\"" |
baaf2337 | 345 | } |
346 | ||
8d3d28f5 | 347 | expect_ssh () { |
710eb3e2 TB |
348 | test_when_finished ' |
349 | (cd "$TRASH_DIRECTORY" && rm -f ssh-expect && >ssh-output) | |
350 | ' && | |
8d3d28f5 | 351 | { |
9f697652 TB |
352 | case "$#" in |
353 | 1) | |
8d3d28f5 | 354 | ;; |
9f697652 | 355 | 2) |
8d3d28f5 | 356 | echo "ssh: $1 git-upload-pack '$2'" |
9f697652 TB |
357 | ;; |
358 | 3) | |
359 | echo "ssh: $1 $2 git-upload-pack '$3'" | |
360 | ;; | |
361 | *) | |
362 | echo "ssh: $1 $2 git-upload-pack '$3' $4" | |
8d3d28f5 NTND |
363 | esac |
364 | } >"$TRASH_DIRECTORY/ssh-expect" && | |
365 | (cd "$TRASH_DIRECTORY" && test_cmp ssh-expect ssh-output) | |
366 | } | |
367 | ||
2171f3d2 | 368 | test_expect_success 'clone myhost:src uses ssh' ' |
3a5728dc | 369 | GIT_TEST_PROTOCOL_VERSION=0 git clone myhost:src ssh-clone && |
8d3d28f5 NTND |
370 | expect_ssh myhost src |
371 | ' | |
372 | ||
f57a8715 | 373 | test_expect_success !MINGW,!CYGWIN 'clone local path foo:bar' ' |
60003340 | 374 | cp -R src "foo:bar" && |
710eb3e2 | 375 | git clone "foo:bar" foobar && |
8d3d28f5 NTND |
376 | expect_ssh none |
377 | ' | |
378 | ||
379 | test_expect_success 'bracketed hostnames are still ssh' ' | |
3a5728dc | 380 | GIT_TEST_PROTOCOL_VERSION=0 git clone "[myhost:123]:src" ssh-bracket-clone && |
d1018c24 | 381 | expect_ssh "-p 123" myhost src |
60003340 NTND |
382 | ' |
383 | ||
94b8ae5a | 384 | test_expect_success 'OpenSSH variant passes -4' ' |
3a5728dc | 385 | GIT_TEST_PROTOCOL_VERSION=0 git clone -4 "[myhost:123]:src" ssh-ipv4-clone && |
94b8ae5a BW |
386 | expect_ssh "-4 -p 123" myhost src |
387 | ' | |
388 | ||
a3f5b66f JN |
389 | test_expect_success 'variant can be overridden' ' |
390 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/putty" && | |
391 | git -c ssh.variant=putty clone -4 "[myhost:123]:src" ssh-putty-clone && | |
392 | expect_ssh "-4 -P 123" myhost src | |
94b8ae5a BW |
393 | ' |
394 | ||
0da0e49b JN |
395 | test_expect_success 'variant=auto picks based on basename' ' |
396 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && | |
397 | git -c ssh.variant=auto clone -4 "[myhost:123]:src" ssh-auto-clone && | |
398 | expect_ssh "-4 -P 123" myhost src | |
399 | ' | |
400 | ||
a3f5b66f | 401 | test_expect_success 'simple does not support -4/-6' ' |
94b8ae5a | 402 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/simple" && |
3fa5e0d0 JN |
403 | test_must_fail git clone -4 "myhost:src" ssh-4-clone-simple |
404 | ' | |
405 | ||
406 | test_expect_success 'simple does not support port' ' | |
407 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/simple" && | |
408 | test_must_fail git clone "[myhost:123]:src" ssh-bracket-clone-simple | |
94b8ae5a BW |
409 | ' |
410 | ||
411 | test_expect_success 'uplink is treated as simple' ' | |
baaf2337 | 412 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/uplink" && |
3fa5e0d0 JN |
413 | test_must_fail git clone "[myhost:123]:src" ssh-bracket-clone-uplink && |
414 | git clone "myhost:src" ssh-clone-uplink && | |
94b8ae5a | 415 | expect_ssh myhost src |
baaf2337 | 416 | ' |
417 | ||
0da0e49b JN |
418 | test_expect_success 'OpenSSH-like uplink is treated as ssh' ' |
419 | write_script "$TRASH_DIRECTORY/uplink" <<-EOF && | |
420 | if test "\$1" = "-G" | |
421 | then | |
422 | exit 0 | |
423 | fi && | |
424 | exec "\$TRASH_DIRECTORY/ssh$X" "\$@" | |
425 | EOF | |
426 | test_when_finished "rm -f \"\$TRASH_DIRECTORY/uplink\"" && | |
427 | GIT_SSH="$TRASH_DIRECTORY/uplink" && | |
428 | test_when_finished "GIT_SSH=\"\$TRASH_DIRECTORY/ssh\$X\"" && | |
3a5728dc | 429 | GIT_TEST_PROTOCOL_VERSION=0 git clone "[myhost:123]:src" ssh-bracket-clone-sshlike-uplink && |
0da0e49b JN |
430 | expect_ssh "-p 123" myhost src |
431 | ' | |
432 | ||
baaf2337 | 433 | test_expect_success 'plink is treated specially (as putty)' ' |
434 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && | |
435 | git clone "[myhost:123]:src" ssh-bracket-clone-plink-0 && | |
436 | expect_ssh "-P 123" myhost src | |
60003340 NTND |
437 | ' |
438 | ||
baaf2337 | 439 | test_expect_success 'plink.exe is treated specially (as putty)' ' |
440 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" && | |
441 | git clone "[myhost:123]:src" ssh-bracket-clone-plink-1 && | |
442 | expect_ssh "-P 123" myhost src | |
443 | ' | |
444 | ||
445 | test_expect_success 'tortoiseplink is like putty, with extra arguments' ' | |
446 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/tortoiseplink" && | |
447 | git clone "[myhost:123]:src" ssh-bracket-clone-plink-2 && | |
448 | expect_ssh "-batch -P 123" myhost src | |
449 | ' | |
450 | ||
e9d9a8a4 SF |
451 | test_expect_success 'double quoted plink.exe in GIT_SSH_COMMAND' ' |
452 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" && | |
453 | GIT_SSH_COMMAND="\"$TRASH_DIRECTORY/plink.exe\" -v" \ | |
454 | git clone "[myhost:123]:src" ssh-bracket-clone-plink-3 && | |
455 | expect_ssh "-v -P 123" myhost src | |
456 | ' | |
457 | ||
e9d9a8a4 SF |
458 | test_expect_success 'single quoted plink.exe in GIT_SSH_COMMAND' ' |
459 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" && | |
460 | GIT_SSH_COMMAND="$SQ$TRASH_DIRECTORY/plink.exe$SQ -v" \ | |
461 | git clone "[myhost:123]:src" ssh-bracket-clone-plink-4 && | |
462 | expect_ssh "-v -P 123" myhost src | |
463 | ' | |
464 | ||
dd33e077 SF |
465 | test_expect_success 'GIT_SSH_VARIANT overrides plink detection' ' |
466 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && | |
3a5728dc JT |
467 | GIT_TEST_PROTOCOL_VERSION=0 GIT_SSH_VARIANT=ssh \ |
468 | git clone "[myhost:123]:src" ssh-bracket-clone-variant-1 && | |
dd33e077 SF |
469 | expect_ssh "-p 123" myhost src |
470 | ' | |
471 | ||
472 | test_expect_success 'ssh.variant overrides plink detection' ' | |
473 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && | |
3a5728dc | 474 | GIT_TEST_PROTOCOL_VERSION=0 git -c ssh.variant=ssh \ |
dd33e077 SF |
475 | clone "[myhost:123]:src" ssh-bracket-clone-variant-2 && |
476 | expect_ssh "-p 123" myhost src | |
477 | ' | |
478 | ||
479 | test_expect_success 'GIT_SSH_VARIANT overrides plink detection to plink' ' | |
8339805b | 480 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && |
dd33e077 SF |
481 | GIT_SSH_VARIANT=plink \ |
482 | git clone "[myhost:123]:src" ssh-bracket-clone-variant-3 && | |
483 | expect_ssh "-P 123" myhost src | |
484 | ' | |
485 | ||
486 | test_expect_success 'GIT_SSH_VARIANT overrides plink to tortoiseplink' ' | |
8339805b | 487 | copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && |
dd33e077 SF |
488 | GIT_SSH_VARIANT=tortoiseplink \ |
489 | git clone "[myhost:123]:src" ssh-bracket-clone-variant-4 && | |
490 | expect_ssh "-batch -P 123" myhost src | |
491 | ' | |
492 | ||
22e5ae5c JK |
493 | test_expect_success 'clean failure on broken quoting' ' |
494 | test_must_fail \ | |
495 | env GIT_SSH_COMMAND="${SQ}plink.exe -v" \ | |
496 | git clone "[myhost:123]:src" sq-failure | |
497 | ' | |
498 | ||
2171f3d2 TB |
499 | counter=0 |
500 | # $1 url | |
501 | # $2 none|host | |
502 | # $3 path | |
503 | test_clone_url () { | |
504 | counter=$(($counter + 1)) | |
3a5728dc | 505 | test_might_fail env GIT_TEST_PROTOCOL_VERSION=0 git clone "$1" tmp$counter && |
9f697652 TB |
506 | shift && |
507 | expect_ssh "$@" | |
2171f3d2 TB |
508 | } |
509 | ||
1cadad6f | 510 | test_expect_success !MINGW,!CYGWIN 'clone c:temp is ssl' ' |
2171f3d2 TB |
511 | test_clone_url c:temp c temp |
512 | ' | |
513 | ||
514 | test_expect_success MINGW 'clone c:temp is dos drive' ' | |
515 | test_clone_url c:temp none | |
516 | ' | |
517 | ||
518 | #ip v4 | |
6a599748 | 519 | for repo in rep rep/home/project 123 |
2171f3d2 TB |
520 | do |
521 | test_expect_success "clone host:$repo" ' | |
522 | test_clone_url host:$repo host $repo | |
523 | ' | |
524 | done | |
525 | ||
526 | #ipv6 | |
2171f3d2 TB |
527 | for repo in rep rep/home/project 123 |
528 | do | |
529 | test_expect_success "clone [::1]:$repo" ' | |
9f697652 | 530 | test_clone_url [::1]:$repo ::1 "$repo" |
2171f3d2 TB |
531 | ' |
532 | done | |
c59ab2e5 TB |
533 | #home directory |
534 | test_expect_success "clone host:/~repo" ' | |
535 | test_clone_url host:/~repo host "~repo" | |
536 | ' | |
537 | ||
538 | test_expect_success "clone [::1]:/~repo" ' | |
539 | test_clone_url [::1]:/~repo ::1 "~repo" | |
540 | ' | |
2171f3d2 TB |
541 | |
542 | # Corner cases | |
83b05875 | 543 | for url in foo/bar:baz [foo]bar/baz:qux [foo/bar]:baz |
2171f3d2 TB |
544 | do |
545 | test_expect_success "clone $url is not ssh" ' | |
546 | test_clone_url $url none | |
547 | ' | |
548 | done | |
549 | ||
550 | #with ssh:// scheme | |
6b6c5f7a TB |
551 | #ignore trailing colon |
552 | for tcol in "" : | |
553 | do | |
554 | test_expect_success "clone ssh://host.xz$tcol/home/user/repo" ' | |
555 | test_clone_url "ssh://host.xz$tcol/home/user/repo" host.xz /home/user/repo | |
556 | ' | |
557 | # from home directory | |
558 | test_expect_success "clone ssh://host.xz$tcol/~repo" ' | |
559 | test_clone_url "ssh://host.xz$tcol/~repo" host.xz "~repo" | |
2171f3d2 | 560 | ' |
6b6c5f7a | 561 | done |
2171f3d2 TB |
562 | |
563 | # with port number | |
564 | test_expect_success 'clone ssh://host.xz:22/home/user/repo' ' | |
565 | test_clone_url "ssh://host.xz:22/home/user/repo" "-p 22 host.xz" "/home/user/repo" | |
566 | ' | |
567 | ||
568 | # from home directory with port number | |
569 | test_expect_success 'clone ssh://host.xz:22/~repo' ' | |
570 | test_clone_url "ssh://host.xz:22/~repo" "-p 22 host.xz" "~repo" | |
571 | ' | |
572 | ||
573 | #IPv6 | |
6b6c5f7a | 574 | for tuah in ::1 [::1] [::1]: user@::1 user@[::1] user@[::1]: [user@::1] [user@::1]: |
9f697652 | 575 | do |
a75a3081 | 576 | ehost=$(echo $tuah | sed -e "s/1]:/1]/" | tr -d "[]") |
9f697652 TB |
577 | test_expect_success "clone ssh://$tuah/home/user/repo" " |
578 | test_clone_url ssh://$tuah/home/user/repo $ehost /home/user/repo | |
579 | " | |
580 | done | |
2171f3d2 TB |
581 | |
582 | #IPv6 from home directory | |
9f697652 TB |
583 | for tuah in ::1 [::1] user@::1 user@[::1] [user@::1] |
584 | do | |
585 | euah=$(echo $tuah | tr -d "[]") | |
586 | test_expect_success "clone ssh://$tuah/~repo" " | |
587 | test_clone_url ssh://$tuah/~repo $euah '~repo' | |
588 | " | |
589 | done | |
2171f3d2 TB |
590 | |
591 | #IPv6 with port number | |
9f697652 TB |
592 | for tuah in [::1] user@[::1] [user@::1] |
593 | do | |
594 | euah=$(echo $tuah | tr -d "[]") | |
595 | test_expect_success "clone ssh://$tuah:22/home/user/repo" " | |
596 | test_clone_url ssh://$tuah:22/home/user/repo '-p 22' $euah /home/user/repo | |
597 | " | |
598 | done | |
2171f3d2 TB |
599 | |
600 | #IPv6 from home directory with port number | |
9f697652 TB |
601 | for tuah in [::1] user@[::1] [user@::1] |
602 | do | |
603 | euah=$(echo $tuah | tr -d "[]") | |
604 | test_expect_success "clone ssh://$tuah:22/~repo" " | |
605 | test_clone_url ssh://$tuah:22/~repo '-p 22' $euah '~repo' | |
606 | " | |
607 | done | |
2171f3d2 | 608 | |
8b277222 JH |
609 | test_expect_success 'clone from a repository with two identical branches' ' |
610 | ||
611 | ( | |
612 | cd src && | |
95cf2c01 | 613 | git checkout -b another main |
8b277222 JH |
614 | ) && |
615 | git clone src target-11 && | |
616 | test "z$( cd target-11 && git symbolic-ref HEAD )" = zrefs/heads/another | |
617 | ||
618 | ' | |
619 | ||
0d7d285f NTND |
620 | test_expect_success 'shallow clone locally' ' |
621 | git clone --depth=1 --no-local src ssrrcc && | |
622 | git clone ssrrcc ddsstt && | |
623 | test_cmp ssrrcc/.git/shallow ddsstt/.git/shallow && | |
624 | ( cd ddsstt && git fsck ) | |
625 | ' | |
626 | ||
32359838 JK |
627 | test_expect_success 'GIT_TRACE_PACKFILE produces a usable pack' ' |
628 | rm -rf dst.git && | |
629 | GIT_TRACE_PACKFILE=$PWD/tmp.pack git clone --no-local --bare src dst.git && | |
630 | git init --bare replay.git && | |
631 | git -C replay.git index-pack -v --stdin <tmp.pack | |
632 | ' | |
633 | ||
b6947af2 ES |
634 | test_expect_success 'clone on case-insensitive fs' ' |
635 | git init icasefs && | |
636 | ( | |
51b85471 | 637 | cd icasefs && |
b6947af2 ES |
638 | o=$(git hash-object -w --stdin </dev/null | hex2oct) && |
639 | t=$(printf "100644 X\0${o}100644 x\0${o}" | | |
640 | git hash-object -w -t tree --stdin) && | |
641 | c=$(git commit-tree -m bogus $t) && | |
642 | git update-ref refs/heads/bogus $c && | |
b878579a | 643 | git clone -b bogus . bogus 2>warning |
b6947af2 ES |
644 | ) |
645 | ' | |
646 | ||
a7f609ec | 647 | test_expect_success CASE_INSENSITIVE_FS 'colliding file detection' ' |
b878579a NTND |
648 | grep X icasefs/warning && |
649 | grep x icasefs/warning && | |
6789275d | 650 | test_grep "the following paths have collided" icasefs/warning |
b878579a NTND |
651 | ' |
652 | ||
47ac9703 | 653 | test_expect_success 'clone with GIT_DEFAULT_HASH' ' |
654 | ( | |
655 | sane_unset GIT_DEFAULT_HASH && | |
656 | git init --object-format=sha1 test-sha1 && | |
657 | git init --object-format=sha256 test-sha256 | |
658 | ) && | |
659 | test_commit -C test-sha1 foo && | |
660 | test_commit -C test-sha256 foo && | |
661 | GIT_DEFAULT_HASH=sha1 git clone test-sha256 test-clone-sha256 && | |
662 | GIT_DEFAULT_HASH=sha256 git clone test-sha1 test-clone-sha1 && | |
663 | git -C test-clone-sha1 status && | |
664 | git -C test-clone-sha256 status | |
665 | ' | |
666 | ||
1c4a9f91 | 667 | partial_clone_server () { |
548719fb | 668 | SERVER="$1" && |
548719fb JT |
669 | |
670 | rm -rf "$SERVER" client && | |
671 | test_create_repo "$SERVER" && | |
672 | test_commit -C "$SERVER" one && | |
44b6c05b | 673 | HASH1=$(git -C "$SERVER" hash-object one.t) && |
548719fb JT |
674 | git -C "$SERVER" revert HEAD && |
675 | test_commit -C "$SERVER" two && | |
44b6c05b | 676 | HASH2=$(git -C "$SERVER" hash-object two.t) && |
548719fb | 677 | test_config -C "$SERVER" uploadpack.allowfilter 1 && |
1c4a9f91 XL |
678 | test_config -C "$SERVER" uploadpack.allowanysha1inwant 1 |
679 | } | |
548719fb | 680 | |
1c4a9f91 XL |
681 | partial_clone () { |
682 | SERVER="$1" && | |
683 | URL="$2" && | |
684 | ||
685 | partial_clone_server "${SERVER}" && | |
548719fb JT |
686 | git clone --filter=blob:limit=0 "$URL" client && |
687 | ||
688 | git -C client fsck && | |
689 | ||
690 | # Ensure that unneeded blobs are not inadvertently fetched. | |
b14ed5ad | 691 | test_config -C client remote.origin.promisor "false" && |
fa3d1b63 | 692 | git -C client config --unset remote.origin.partialclonefilter && |
548719fb JT |
693 | test_must_fail git -C client cat-file -e "$HASH1" && |
694 | ||
695 | # But this blob was fetched, because clone performs an initial checkout | |
696 | git -C client cat-file -e "$HASH2" | |
697 | } | |
698 | ||
699 | test_expect_success 'partial clone' ' | |
700 | partial_clone server "file://$(pwd)/server" | |
701 | ' | |
702 | ||
1c4a9f91 XL |
703 | test_expect_success 'partial clone with -o' ' |
704 | partial_clone_server server && | |
23547c40 JT |
705 | git clone -o blah --filter=blob:limit=0 "file://$(pwd)/server" client && |
706 | test_cmp_config -C client "blob:limit=0" --get-all remote.blah.partialclonefilter | |
1c4a9f91 XL |
707 | ' |
708 | ||
548719fb JT |
709 | test_expect_success 'partial clone: warn if server does not support object filtering' ' |
710 | rm -rf server client && | |
711 | test_create_repo server && | |
712 | test_commit -C server one && | |
713 | ||
714 | git clone --filter=blob:limit=0 "file://$(pwd)/server" client 2> err && | |
715 | ||
6789275d | 716 | test_grep "filtering not recognized by server" err |
548719fb JT |
717 | ' |
718 | ||
c0c578b3 JT |
719 | test_expect_success 'batch missing blob request during checkout' ' |
720 | rm -rf server client && | |
721 | ||
722 | test_create_repo server && | |
723 | echo a >server/a && | |
724 | echo b >server/b && | |
725 | git -C server add a b && | |
726 | ||
727 | git -C server commit -m x && | |
728 | echo aa >server/a && | |
729 | echo bb >server/b && | |
730 | git -C server add a b && | |
731 | git -C server commit -m x && | |
732 | ||
733 | test_config -C server uploadpack.allowfilter 1 && | |
734 | test_config -C server uploadpack.allowanysha1inwant 1 && | |
735 | ||
736 | git clone --filter=blob:limit=0 "file://$(pwd)/server" client && | |
737 | ||
738 | # Ensure that there is only one negotiation by checking that there is | |
739 | # only "done" line sent. ("done" marks the end of negotiation.) | |
a29263cf JS |
740 | GIT_TRACE_PACKET="$(pwd)/trace" \ |
741 | GIT_TRACE2_EVENT="$(pwd)/trace2_event" \ | |
742 | git -C client -c trace2.eventNesting=5 checkout HEAD^ && | |
743 | grep \"key\":\"total_rounds\",\"value\":\"1\" trace2_event >trace_lines && | |
744 | test_line_count = 1 trace_lines && | |
7ca3c0ac | 745 | grep "fetch> done" trace >done_lines && |
c0c578b3 JT |
746 | test_line_count = 1 done_lines |
747 | ' | |
748 | ||
749 | test_expect_success 'batch missing blob request does not inadvertently try to fetch gitlinks' ' | |
750 | rm -rf server client && | |
751 | ||
752 | test_create_repo repo_for_submodule && | |
753 | test_commit -C repo_for_submodule x && | |
754 | ||
755 | test_create_repo server && | |
756 | echo a >server/a && | |
757 | echo b >server/b && | |
758 | git -C server add a b && | |
759 | git -C server commit -m x && | |
760 | ||
761 | echo aa >server/a && | |
762 | echo bb >server/b && | |
763 | # Also add a gitlink pointing to an arbitrary repository | |
225d2d50 | 764 | test_config_global protocol.file.allow always && |
c0c578b3 JT |
765 | git -C server submodule add "$(pwd)/repo_for_submodule" c && |
766 | git -C server add a b c && | |
767 | git -C server commit -m x && | |
768 | ||
769 | test_config -C server uploadpack.allowfilter 1 && | |
770 | test_config -C server uploadpack.allowanysha1inwant 1 && | |
771 | ||
772 | # Make sure that it succeeds | |
773 | git clone --filter=blob:limit=0 "file://$(pwd)/server" client | |
774 | ' | |
775 | ||
548719fb JT |
776 | . "$TEST_DIRECTORY"/lib-httpd.sh |
777 | start_httpd | |
778 | ||
779 | test_expect_success 'partial clone using HTTP' ' | |
780 | partial_clone "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server" | |
781 | ' | |
782 | ||
4fe788b1 LL |
783 | test_expect_success 'reject cloning shallow repository using HTTP' ' |
784 | test_when_finished "rm -rf repo" && | |
785 | git clone --bare --no-local --depth=1 src "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && | |
b89c7312 | 786 | test_must_fail git -c protocol.version=2 clone --reject-shallow $HTTPD_URL/smart/repo.git repo 2>err && |
6789275d | 787 | test_grep -e "source repository is shallow, reject to clone." err && |
4fe788b1 LL |
788 | |
789 | git clone --no-reject-shallow $HTTPD_URL/smart/repo.git repo | |
790 | ' | |
791 | ||
876094ac DS |
792 | test_expect_success 'auto-discover bundle URI from HTTP clone' ' |
793 | test_when_finished rm -rf trace.txt repo2 "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" && | |
794 | git -C src bundle create "$HTTPD_DOCUMENT_ROOT_PATH/everything.bundle" --all && | |
795 | git clone --bare --no-local src "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" && | |
796 | ||
797 | git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" config \ | |
798 | uploadpack.advertiseBundleURIs true && | |
799 | git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" config \ | |
800 | bundle.version 1 && | |
801 | git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" config \ | |
802 | bundle.mode all && | |
803 | git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo2.git" config \ | |
804 | bundle.everything.uri "$HTTPD_URL/everything.bundle" && | |
805 | ||
806 | GIT_TRACE2_EVENT="$(pwd)/trace.txt" \ | |
807 | git -c protocol.version=2 \ | |
808 | -c transfer.bundleURI=true clone \ | |
809 | $HTTPD_URL/smart/repo2.git repo2 && | |
810 | cat >pattern <<-EOF && | |
811 | "event":"child_start".*"argv":\["git-remote-https","$HTTPD_URL/everything.bundle"\] | |
812 | EOF | |
813 | grep -f pattern trace.txt | |
814 | ' | |
815 | ||
816 | test_expect_success 'auto-discover multiple bundles from HTTP clone' ' | |
817 | test_when_finished rm -rf trace.txt repo3 "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" && | |
818 | ||
819 | test_commit -C src new && | |
820 | git -C src bundle create "$HTTPD_DOCUMENT_ROOT_PATH/new.bundle" HEAD~1..HEAD && | |
821 | git clone --bare --no-local src "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" && | |
822 | ||
823 | git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \ | |
824 | uploadpack.advertiseBundleURIs true && | |
825 | git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \ | |
826 | bundle.version 1 && | |
827 | git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \ | |
828 | bundle.mode all && | |
829 | ||
830 | git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \ | |
831 | bundle.everything.uri "$HTTPD_URL/everything.bundle" && | |
832 | git -C "$HTTPD_DOCUMENT_ROOT_PATH/repo3.git" config \ | |
833 | bundle.new.uri "$HTTPD_URL/new.bundle" && | |
834 | ||
835 | GIT_TRACE2_EVENT="$(pwd)/trace.txt" \ | |
836 | git -c protocol.version=2 \ | |
837 | -c transfer.bundleURI=true clone \ | |
838 | $HTTPD_URL/smart/repo3.git repo3 && | |
839 | ||
840 | # We should fetch _both_ bundles | |
841 | cat >pattern <<-EOF && | |
842 | "event":"child_start".*"argv":\["git-remote-https","$HTTPD_URL/everything.bundle"\] | |
843 | EOF | |
844 | grep -f pattern trace.txt && | |
845 | cat >pattern <<-EOF && | |
846 | "event":"child_start".*"argv":\["git-remote-https","$HTTPD_URL/new.bundle"\] | |
847 | EOF | |
848 | grep -f pattern trace.txt | |
849 | ' | |
850 | ||
7903efb7 DS |
851 | test_expect_success 'auto-discover multiple bundles from HTTP clone: creationToken heuristic' ' |
852 | test_when_finished rm -rf "$HTTPD_DOCUMENT_ROOT_PATH/repo4.git" && | |
853 | test_when_finished rm -rf clone-heuristic trace*.txt && | |
854 | ||
855 | test_commit -C src newest && | |
856 | git -C src bundle create "$HTTPD_DOCUMENT_ROOT_PATH/newest.bundle" HEAD~1..HEAD && | |
857 | git clone --bare --no-local src "$HTTPD_DOCUMENT_ROOT_PATH/repo4.git" && | |
858 | ||
859 | cat >>"$HTTPD_DOCUMENT_ROOT_PATH/repo4.git/config" <<-EOF && | |
860 | [uploadPack] | |
861 | advertiseBundleURIs = true | |
862 | ||
863 | [bundle] | |
864 | version = 1 | |
865 | mode = all | |
866 | heuristic = creationToken | |
867 | ||
868 | [bundle "everything"] | |
869 | uri = $HTTPD_URL/everything.bundle | |
870 | creationtoken = 1 | |
871 | ||
872 | [bundle "new"] | |
873 | uri = $HTTPD_URL/new.bundle | |
874 | creationtoken = 2 | |
875 | ||
876 | [bundle "newest"] | |
877 | uri = $HTTPD_URL/newest.bundle | |
878 | creationtoken = 3 | |
879 | EOF | |
880 | ||
881 | GIT_TRACE2_EVENT="$(pwd)/trace-clone.txt" \ | |
882 | git -c protocol.version=2 \ | |
883 | -c transfer.bundleURI=true clone \ | |
884 | "$HTTPD_URL/smart/repo4.git" clone-heuristic && | |
885 | ||
886 | cat >expect <<-EOF && | |
887 | $HTTPD_URL/newest.bundle | |
888 | $HTTPD_URL/new.bundle | |
889 | $HTTPD_URL/everything.bundle | |
890 | EOF | |
891 | ||
892 | # We should fetch all bundles in the expected order. | |
893 | test_remote_https_urls <trace-clone.txt >actual && | |
894 | test_cmp expect actual | |
895 | ' | |
896 | ||
decfe05b SG |
897 | # DO NOT add non-httpd-specific tests here, because the last part of this |
898 | # test script is only executed when httpd is available and enabled. | |
899 | ||
a2b26acd | 900 | test_done |