Git fork
at reftables-rust 1528 lines 50 kB view raw
1#!/bin/sh 2 3test_description='test git wire-protocol version 2' 4 5TEST_NO_CREATE_REPO=1 6 7GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 8export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 9 10. ./test-lib.sh 11 12# Test protocol v2 with 'git://' transport 13# 14. "$TEST_DIRECTORY"/lib-git-daemon.sh 15start_git_daemon --export-all --enable=receive-pack 16daemon_parent=$GIT_DAEMON_DOCUMENT_ROOT_PATH/parent 17 18test_expect_success 'create repo to be served by git-daemon' ' 19 git init "$daemon_parent" && 20 test_commit -C "$daemon_parent" one 21' 22 23test_expect_success 'list refs with git:// using protocol v2' ' 24 test_when_finished "rm -f log" && 25 26 GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ 27 ls-remote --symref "$GIT_DAEMON_URL/parent" >actual && 28 29 # Client requested to use protocol v2 30 grep "ls-remote> .*\\\0\\\0version=2\\\0$" log && 31 # Server responded using protocol v2 32 grep "ls-remote< version 2" log && 33 34 git ls-remote --symref "$GIT_DAEMON_URL/parent" >expect && 35 test_cmp expect actual 36' 37 38test_expect_success 'ref advertisement is filtered with ls-remote using protocol v2' ' 39 test_when_finished "rm -f log" && 40 41 GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ 42 ls-remote "$GIT_DAEMON_URL/parent" main >actual && 43 44 cat >expect <<-EOF && 45 $(git -C "$daemon_parent" rev-parse refs/heads/main)$(printf "\t")refs/heads/main 46 EOF 47 48 test_cmp expect actual 49' 50 51test_expect_success 'clone with git:// using protocol v2' ' 52 test_when_finished "rm -f log" && 53 54 GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ 55 clone "$GIT_DAEMON_URL/parent" daemon_child && 56 57 git -C daemon_child log -1 --format=%s >actual && 58 git -C "$daemon_parent" log -1 --format=%s >expect && 59 test_cmp expect actual && 60 61 # Client requested to use protocol v2 62 grep "clone> .*\\\0\\\0version=2\\\0$" log && 63 # Server responded using protocol v2 64 grep "clone< version 2" log 65' 66 67test_expect_success 'fetch with git:// using protocol v2' ' 68 test_when_finished "rm -f log" && 69 70 test_commit -C "$daemon_parent" two && 71 72 GIT_TRACE_PACKET="$(pwd)/log" git -C daemon_child -c protocol.version=2 \ 73 fetch && 74 75 git -C daemon_child log -1 --format=%s origin/main >actual && 76 git -C "$daemon_parent" log -1 --format=%s >expect && 77 test_cmp expect actual && 78 79 # Client requested to use protocol v2 80 grep "fetch> .*\\\0\\\0version=2\\\0$" log && 81 # Server responded using protocol v2 82 grep "fetch< version 2" log 83' 84 85test_expect_success 'fetch by hash without tag following with protocol v2 does not list refs' ' 86 test_when_finished "rm -f log" && 87 88 test_commit -C "$daemon_parent" two_a && 89 git -C "$daemon_parent" rev-parse two_a >two_a_hash && 90 91 GIT_TRACE_PACKET="$(pwd)/log" git -C daemon_child -c protocol.version=2 \ 92 fetch --no-tags origin $(cat two_a_hash) && 93 94 grep "fetch< version 2" log && 95 ! grep "fetch> command=ls-refs" log 96' 97 98test_expect_success 'pull with git:// using protocol v2' ' 99 test_when_finished "rm -f log" && 100 101 GIT_TRACE_PACKET="$(pwd)/log" git -C daemon_child -c protocol.version=2 \ 102 pull && 103 104 git -C daemon_child log -1 --format=%s >actual && 105 git -C "$daemon_parent" log -1 --format=%s >expect && 106 test_cmp expect actual && 107 108 # Client requested to use protocol v2 109 grep "fetch> .*\\\0\\\0version=2\\\0$" log && 110 # Server responded using protocol v2 111 grep "fetch< version 2" log 112' 113 114test_expect_success 'push with git:// and a config of v2 does not request v2' ' 115 test_when_finished "rm -f log" && 116 117 # Till v2 for push is designed, make sure that if a client has 118 # protocol.version configured to use v2, that the client instead falls 119 # back and uses v0. 120 121 test_commit -C daemon_child three && 122 123 # Push to another branch, as the target repository has the 124 # main branch checked out and we cannot push into it. 125 GIT_TRACE_PACKET="$(pwd)/log" git -C daemon_child -c protocol.version=2 \ 126 push origin HEAD:client_branch && 127 128 git -C daemon_child log -1 --format=%s >actual && 129 git -C "$daemon_parent" log -1 --format=%s client_branch >expect && 130 test_cmp expect actual && 131 132 # Client requested to use protocol v2 133 ! grep "push> .*\\\0\\\0version=2\\\0$" log && 134 # Server responded using protocol v2 135 ! grep "push< version 2" log 136' 137 138stop_git_daemon 139 140# Test protocol v2 with 'file://' transport 141# 142test_expect_success 'create repo to be served by file:// transport' ' 143 git init file_parent && 144 test_commit -C file_parent one 145' 146 147test_expect_success 'list refs with file:// using protocol v2' ' 148 test_when_finished "rm -f log" && 149 150 GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ 151 ls-remote --symref "file://$(pwd)/file_parent" >actual && 152 153 # Server responded using protocol v2 154 grep "ls-remote< version 2" log && 155 156 git ls-remote --symref "file://$(pwd)/file_parent" >expect && 157 test_cmp expect actual 158' 159 160test_expect_success 'ref advertisement is filtered with ls-remote using protocol v2' ' 161 test_when_finished "rm -f log" && 162 163 GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ 164 ls-remote "file://$(pwd)/file_parent" main >actual && 165 166 cat >expect <<-EOF && 167 $(git -C file_parent rev-parse refs/heads/main)$(printf "\t")refs/heads/main 168 EOF 169 170 test_cmp expect actual 171' 172 173test_expect_success 'server-options are sent when using ls-remote' ' 174 test_when_finished "rm -f log" && 175 176 GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ 177 ls-remote -o hello -o world "file://$(pwd)/file_parent" main >actual && 178 179 cat >expect <<-EOF && 180 $(git -C file_parent rev-parse refs/heads/main)$(printf "\t")refs/heads/main 181 EOF 182 183 test_cmp expect actual && 184 grep "server-option=hello" log && 185 grep "server-option=world" log 186' 187 188test_expect_success 'server-options from configuration are used by ls-remote' ' 189 test_when_finished "rm -rf log myclone" && 190 git clone "file://$(pwd)/file_parent" myclone && 191 cat >expect <<-EOF && 192 $(git -C file_parent rev-parse refs/heads/main)$(printf "\t")refs/heads/main 193 EOF 194 195 # Default server options from configuration are used 196 git -C myclone config --add remote.origin.serverOption foo && 197 git -C myclone config --add remote.origin.serverOption bar && 198 GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \ 199 ls-remote origin main >actual && 200 test_cmp expect actual && 201 test_grep "ls-remote> server-option=foo" log && 202 test_grep "ls-remote> server-option=bar" log && 203 rm -f log && 204 205 # Empty value of remote.<name>.serverOption clears the list 206 git -C myclone config --add remote.origin.serverOption "" && 207 git -C myclone config --add remote.origin.serverOption tar && 208 GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \ 209 ls-remote origin main >actual && 210 test_cmp expect actual && 211 test_grep "ls-remote> server-option=tar" log && 212 test_grep ! "ls-remote> server-option=foo" log && 213 test_grep ! "ls-remote> server-option=bar" log && 214 rm -f log && 215 216 # Server option from command line overrides those from configuration 217 GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \ 218 ls-remote -o hello -o world origin main >actual && 219 test_cmp expect actual && 220 test_grep "ls-remote> server-option=hello" log && 221 test_grep "ls-remote> server-option=world" log && 222 test_grep ! "ls-remote> server-option=tar" log 223' 224 225test_expect_success 'warn if using server-option with ls-remote with legacy protocol' ' 226 test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \ 227 ls-remote -o hello -o world "file://$(pwd)/file_parent" main 2>err && 228 229 test_grep "see protocol.version in" err && 230 test_grep "server options require protocol version 2 or later" err 231' 232 233test_expect_success 'clone with file:// using protocol v2' ' 234 test_when_finished "rm -f log" && 235 236 GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ 237 clone "file://$(pwd)/file_parent" file_child && 238 239 git -C file_child log -1 --format=%s >actual && 240 git -C file_parent log -1 --format=%s >expect && 241 test_cmp expect actual && 242 243 # Server responded using protocol v2 244 grep "clone< version 2" log && 245 246 # Client sent ref-prefixes to filter the ref-advertisement 247 grep "ref-prefix HEAD" log && 248 grep "ref-prefix refs/heads/" log && 249 grep "ref-prefix refs/tags/" log 250' 251 252test_expect_success 'clone of empty repo propagates name of default branch' ' 253 test_when_finished "rm -rf file_empty_parent file_empty_child" && 254 255 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \ 256 git -c init.defaultBranch=mydefaultbranch init file_empty_parent && 257 258 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \ 259 git -c init.defaultBranch=main -c protocol.version=2 \ 260 clone "file://$(pwd)/file_empty_parent" file_empty_child && 261 echo refs/heads/mydefaultbranch >expect && 262 git -C file_empty_child symbolic-ref HEAD >actual && 263 test_cmp expect actual 264' 265 266test_expect_success '...but not if explicitly forbidden by config' ' 267 test_when_finished "rm -rf file_empty_parent file_empty_child" && 268 269 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \ 270 git -c init.defaultBranch=mydefaultbranch init file_empty_parent && 271 test_config -C file_empty_parent lsrefs.unborn ignore && 272 273 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \ 274 git -c init.defaultBranch=main -c protocol.version=2 \ 275 clone "file://$(pwd)/file_empty_parent" file_empty_child && 276 echo refs/heads/main >expect && 277 git -C file_empty_child symbolic-ref HEAD >actual && 278 test_cmp expect actual 279' 280 281test_expect_success 'bare clone propagates empty default branch' ' 282 test_when_finished "rm -rf file_empty_parent file_empty_child.git" && 283 284 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \ 285 git -c init.defaultBranch=mydefaultbranch init file_empty_parent && 286 287 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \ 288 git -c init.defaultBranch=main -c protocol.version=2 \ 289 clone --bare \ 290 "file://$(pwd)/file_empty_parent" file_empty_child.git && 291 echo "refs/heads/mydefaultbranch" >expect && 292 git -C file_empty_child.git symbolic-ref HEAD >actual && 293 test_cmp expect actual 294' 295 296test_expect_success 'clone propagates unborn HEAD from non-empty repo' ' 297 test_when_finished "rm -rf file_unborn_parent file_unborn_child" && 298 299 git init file_unborn_parent && 300 ( 301 cd file_unborn_parent && 302 git checkout -b branchwithstuff && 303 test_commit --no-tag stuff && 304 git symbolic-ref HEAD refs/heads/mydefaultbranch 305 ) && 306 307 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \ 308 git -c init.defaultBranch=main -c protocol.version=2 \ 309 clone "file://$(pwd)/file_unborn_parent" \ 310 file_unborn_child 2>stderr && 311 echo "refs/heads/mydefaultbranch" >expect && 312 git -C file_unborn_child symbolic-ref HEAD >actual && 313 test_cmp expect actual && 314 grep "warning: remote HEAD refers to nonexistent ref" stderr 315' 316 317test_expect_success 'clone propagates object-format from empty repo' ' 318 test_when_finished "rm -fr src256 dst256" && 319 320 echo sha256 >expect && 321 git init --object-format=sha256 src256 && 322 git clone src256 dst256 && 323 git -C dst256 rev-parse --show-object-format >actual && 324 325 test_cmp expect actual 326' 327 328test_expect_success 'bare clone propagates unborn HEAD from non-empty repo' ' 329 test_when_finished "rm -rf file_unborn_parent file_unborn_child.git" && 330 331 git init file_unborn_parent && 332 ( 333 cd file_unborn_parent && 334 git checkout -b branchwithstuff && 335 test_commit --no-tag stuff && 336 git symbolic-ref HEAD refs/heads/mydefaultbranch 337 ) && 338 339 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \ 340 git -c init.defaultBranch=main -c protocol.version=2 \ 341 clone --bare "file://$(pwd)/file_unborn_parent" \ 342 file_unborn_child.git 2>stderr && 343 echo "refs/heads/mydefaultbranch" >expect && 344 git -C file_unborn_child.git symbolic-ref HEAD >actual && 345 test_cmp expect actual && 346 ! grep "warning:" stderr 347' 348 349test_expect_success 'defaulted HEAD uses remote branch if available' ' 350 test_when_finished "rm -rf file_unborn_parent file_unborn_child" && 351 352 git init file_unborn_parent && 353 ( 354 cd file_unborn_parent && 355 git config lsrefs.unborn ignore && 356 git checkout -b branchwithstuff && 357 test_commit --no-tag stuff && 358 git symbolic-ref HEAD refs/heads/mydefaultbranch 359 ) && 360 361 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \ 362 git -c init.defaultBranch=branchwithstuff -c protocol.version=2 \ 363 clone "file://$(pwd)/file_unborn_parent" \ 364 file_unborn_child 2>stderr && 365 echo "refs/heads/branchwithstuff" >expect && 366 git -C file_unborn_child symbolic-ref HEAD >actual && 367 test_cmp expect actual && 368 test_path_is_file file_unborn_child/stuff.t && 369 ! grep "warning:" stderr 370' 371 372test_expect_success 'fetch with file:// using protocol v2' ' 373 test_when_finished "rm -f log" && 374 375 test_commit -C file_parent two && 376 377 GIT_TRACE_PACKET="$(pwd)/log" git -C file_child -c protocol.version=2 \ 378 fetch origin && 379 380 git -C file_child log -1 --format=%s origin/main >actual && 381 git -C file_parent log -1 --format=%s >expect && 382 test_cmp expect actual && 383 384 # Server responded using protocol v2 385 grep "fetch< version 2" log 386' 387 388test_expect_success 'ref advertisement is filtered during fetch using protocol v2' ' 389 test_when_finished "rm -f log" && 390 391 test_commit -C file_parent three && 392 git -C file_parent branch unwanted-branch three && 393 394 GIT_TRACE_PACKET="$(pwd)/log" git -C file_child -c protocol.version=2 \ 395 fetch origin main && 396 397 git -C file_child log -1 --format=%s origin/main >actual && 398 git -C file_parent log -1 --format=%s >expect && 399 test_cmp expect actual && 400 401 grep "refs/heads/main" log && 402 ! grep "refs/heads/unwanted-branch" log 403' 404 405test_expect_success 'server-options are sent when fetching' ' 406 test_when_finished "rm -f log" && 407 408 test_commit -C file_parent four && 409 410 GIT_TRACE_PACKET="$(pwd)/log" git -C file_child -c protocol.version=2 \ 411 fetch -o hello -o world origin main && 412 413 git -C file_child log -1 --format=%s origin/main >actual && 414 git -C file_parent log -1 --format=%s >expect && 415 test_cmp expect actual && 416 417 grep "server-option=hello" log && 418 grep "server-option=world" log 419' 420 421test_expect_success 'server-options are sent when fetch multiple remotes' ' 422 test_when_finished "rm -f log server_options_sent" && 423 git clone "file://$(pwd)/file_parent" child_multi_remotes && 424 git -C child_multi_remotes remote add another "file://$(pwd)/file_parent" && 425 GIT_TRACE_PACKET="$(pwd)/log" git -C child_multi_remotes -c protocol.version=2 \ 426 fetch -o hello --all && 427 grep "fetch> server-option=hello" log >server_options_sent && 428 test_line_count = 2 server_options_sent 429' 430 431test_expect_success 'server-options from configuration are used by git-fetch' ' 432 test_when_finished "rm -rf log myclone" && 433 git clone "file://$(pwd)/file_parent" myclone && 434 git -C file_parent log -1 --format=%s >expect && 435 436 # Default server options from configuration are used 437 git -C myclone config --add remote.origin.serverOption foo && 438 git -C myclone config --add remote.origin.serverOption bar && 439 GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \ 440 fetch origin main && 441 git -C myclone log -1 --format=%s origin/main >actual && 442 test_cmp expect actual && 443 test_grep "fetch> server-option=foo" log && 444 test_grep "fetch> server-option=bar" log && 445 rm -f log && 446 447 # Empty value of remote.<name>.serverOption clears the list 448 git -C myclone config --add remote.origin.serverOption "" && 449 git -C myclone config --add remote.origin.serverOption tar && 450 GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \ 451 fetch origin main && 452 git -C myclone log -1 --format=%s origin/main >actual && 453 test_cmp expect actual && 454 test_grep "fetch> server-option=tar" log && 455 test_grep ! "fetch> server-option=foo" log && 456 test_grep ! "fetch> server-option=bar" log && 457 rm -f log && 458 459 # Server option from command line overrides those from configuration 460 GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \ 461 fetch -o hello -o world origin main && 462 git -C myclone log -1 --format=%s origin/main >actual && 463 test_cmp expect actual && 464 test_grep "fetch> server-option=hello" log && 465 test_grep "fetch> server-option=world" log && 466 test_grep ! "fetch> server-option=tar" log 467' 468 469test_expect_success 'warn if using server-option with fetch with legacy protocol' ' 470 test_when_finished "rm -rf temp_child" && 471 472 git init temp_child && 473 474 test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -C temp_child -c protocol.version=0 \ 475 fetch -o hello -o world "file://$(pwd)/file_parent" main 2>err && 476 477 test_grep "see protocol.version in" err && 478 test_grep "server options require protocol version 2 or later" err 479' 480 481test_expect_success 'server-options are sent when cloning' ' 482 test_when_finished "rm -rf log myclone" && 483 484 GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ 485 clone --server-option=hello --server-option=world \ 486 "file://$(pwd)/file_parent" myclone && 487 488 grep "server-option=hello" log && 489 grep "server-option=world" log 490' 491 492test_expect_success 'server-options from configuration are used by git-clone' ' 493 test_when_finished "rm -rf log myclone" && 494 495 # Default server options from configuration are used 496 GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ 497 -c remote.origin.serverOption=foo -c remote.origin.serverOption=bar \ 498 clone "file://$(pwd)/file_parent" myclone && 499 test_grep "clone> server-option=foo" log && 500 test_grep "clone> server-option=bar" log && 501 rm -rf log myclone && 502 503 # Empty value of remote.<name>.serverOption clears the list 504 GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ 505 -c remote.origin.serverOption=foo -c remote.origin.serverOption=bar \ 506 -c remote.origin.serverOption= -c remote.origin.serverOption=tar \ 507 clone "file://$(pwd)/file_parent" myclone && 508 test_grep "clone> server-option=tar" log && 509 test_grep ! "clone> server-option=foo" log && 510 test_grep ! "clone> server-option=bar" log && 511 rm -rf log myclone && 512 513 # Server option from command line overrides those from configuration 514 GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ 515 -c remote.origin.serverOption=tar \ 516 clone --server-option=hello --server-option=world \ 517 "file://$(pwd)/file_parent" myclone && 518 test_grep "clone> server-option=hello" log && 519 test_grep "clone> server-option=world" log && 520 test_grep ! "clone> server-option=tar" log 521' 522 523test_expect_success 'warn if using server-option with clone with legacy protocol' ' 524 test_when_finished "rm -rf myclone" && 525 526 test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \ 527 clone --server-option=hello --server-option=world \ 528 "file://$(pwd)/file_parent" myclone 2>err && 529 530 test_grep "see protocol.version in" err && 531 test_grep "server options require protocol version 2 or later" err 532' 533 534test_expect_success 'server-option configuration with legacy protocol is ok' ' 535 test_when_finished "rm -rf myclone" && 536 537 env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \ 538 -c remote.origin.serverOption=foo -c remote.origin.serverOption=bar \ 539 clone "file://$(pwd)/file_parent" myclone 540' 541 542test_expect_success 'invalid server-option configuration' ' 543 test_when_finished "rm -rf myclone" && 544 545 test_must_fail git -c protocol.version=2 \ 546 -c remote.origin.serverOption \ 547 clone "file://$(pwd)/file_parent" myclone 2>err && 548 test_grep "error: missing value for '\''remote.origin.serveroption'\''" err 549' 550 551test_expect_success 'upload-pack respects config using protocol v2' ' 552 git init server && 553 write_script server/.git/hook <<-\EOF && 554 touch hookout 555 "$@" 556 EOF 557 test_commit -C server one && 558 559 test_config_global uploadpack.packobjectshook ./hook && 560 test_path_is_missing server/.git/hookout && 561 git -c protocol.version=2 clone "file://$(pwd)/server" client && 562 test_path_is_file server/.git/hookout 563' 564 565test_expect_success 'setup filter tests' ' 566 rm -rf server client && 567 git init server && 568 569 # 1 commit to create a file, and 1 commit to modify it 570 test_commit -C server message1 a.txt && 571 test_commit -C server message2 a.txt && 572 git -C server config protocol.version 2 && 573 git -C server config uploadpack.allowfilter 1 && 574 git -C server config uploadpack.allowanysha1inwant 1 && 575 git -C server config protocol.version 2 576' 577 578test_expect_success 'partial clone' ' 579 GIT_TRACE_PACKET="$(pwd)/trace" git -c protocol.version=2 \ 580 clone --filter=blob:none "file://$(pwd)/server" client && 581 grep "version 2" trace && 582 583 # Ensure that the old version of the file is missing 584 git -C client rev-list --quiet --objects --missing=print main \ 585 >observed.oids && 586 grep "$(git -C server rev-parse message1:a.txt)" observed.oids && 587 588 # Ensure that client passes fsck 589 git -C client fsck 590' 591 592test_expect_success 'dynamically fetch missing object' ' 593 rm "$(pwd)/trace" && 594 GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \ 595 cat-file -p $(git -C server rev-parse message1:a.txt) && 596 grep "version 2" trace 597' 598 599test_expect_success 'when dynamically fetching missing object, do not list refs' ' 600 ! grep "git> command=ls-refs" trace 601' 602 603test_expect_success 'partial fetch' ' 604 rm -rf client "$(pwd)/trace" && 605 git init client && 606 SERVER="file://$(pwd)/server" && 607 608 GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \ 609 fetch --filter=blob:none "$SERVER" main:refs/heads/other && 610 grep "version 2" trace && 611 612 # Ensure that the old version of the file is missing 613 git -C client rev-list --quiet --objects --missing=print other \ 614 >observed.oids && 615 grep "$(git -C server rev-parse message1:a.txt)" observed.oids && 616 617 # Ensure that client passes fsck 618 git -C client fsck 619' 620 621test_expect_success 'do not advertise filter if not configured to do so' ' 622 SERVER="file://$(pwd)/server" && 623 624 rm "$(pwd)/trace" && 625 git -C server config uploadpack.allowfilter 1 && 626 GIT_TRACE_PACKET="$(pwd)/trace" git -c protocol.version=2 \ 627 ls-remote "$SERVER" && 628 grep "fetch=.*filter" trace && 629 630 rm "$(pwd)/trace" && 631 git -C server config uploadpack.allowfilter 0 && 632 GIT_TRACE_PACKET="$(pwd)/trace" git -c protocol.version=2 \ 633 ls-remote "$SERVER" && 634 grep "fetch=" trace >fetch_capabilities && 635 ! grep filter fetch_capabilities 636' 637 638test_expect_success 'partial clone warns if filter is not advertised' ' 639 rm -rf client && 640 git -C server config uploadpack.allowfilter 0 && 641 git -c protocol.version=2 \ 642 clone --filter=blob:none "file://$(pwd)/server" client 2>err && 643 test_grep "filtering not recognized by server, ignoring" err 644' 645 646test_expect_success 'even with handcrafted request, filter does not work if not advertised' ' 647 git -C server config uploadpack.allowfilter 0 && 648 649 # Custom request that tries to filter even though it is not advertised. 650 test-tool pkt-line pack >in <<-EOF && 651 command=fetch 652 object-format=$(test_oid algo) 653 0001 654 want $(git -C server rev-parse main) 655 filter blob:none 656 0000 657 EOF 658 659 test_must_fail test-tool -C server serve-v2 --stateless-rpc \ 660 <in >/dev/null 2>err && 661 grep "unexpected line: .filter blob:none." err && 662 663 # Exercise to ensure that if advertised, filter works 664 git -C server config uploadpack.allowfilter 1 && 665 test-tool -C server serve-v2 --stateless-rpc <in >/dev/null 666' 667 668test_expect_success 'default refspec is used to filter ref when fetching' ' 669 test_when_finished "rm -f log" && 670 671 GIT_TRACE_PACKET="$(pwd)/log" git -C file_child -c protocol.version=2 \ 672 fetch origin && 673 674 git -C file_child log -1 --format=%s three >actual && 675 git -C file_parent log -1 --format=%s three >expect && 676 test_cmp expect actual && 677 678 grep "ref-prefix refs/heads/" log && 679 grep "ref-prefix refs/tags/" log 680' 681 682test_expect_success 'set up parent for prefix tests' ' 683 git init prefix-parent && 684 git -C prefix-parent commit --allow-empty -m foo && 685 git -C prefix-parent tag my-tag && 686 git -C prefix-parent branch unrelated-branch 687' 688 689test_expect_success 'empty refspec filters refs when fetching' ' 690 git init configless-child && 691 692 test_when_finished "rm -f log" && 693 GIT_TRACE_PACKET="$(pwd)/log" \ 694 git -C configless-child fetch ../prefix-parent && 695 test_grep ! unrelated-branch log 696' 697 698test_expect_success 'exact oid fetch with tag following' ' 699 git init exact-oid-tags && 700 701 commit=$(git -C prefix-parent rev-parse --verify HEAD) && 702 703 test_when_finished "rm -f log" && 704 GIT_TRACE_PACKET="$(pwd)/log" \ 705 git -C exact-oid-tags fetch ../prefix-parent \ 706 $commit:refs/heads/exact && 707 test_grep ! unrelated-branch log && 708 git -C exact-oid-tags rev-parse --verify my-tag 709' 710 711test_expect_success 'exact oid fetch avoids pointless HEAD request' ' 712 git init exact-oid-head && 713 git -C exact-oid-head remote add origin ../prefix-parent && 714 715 commit=$(git -C prefix-parent rev-parse --verify HEAD) && 716 717 test_when_finished "rm -f log" && 718 GIT_TRACE_PACKET="$(pwd)/log" \ 719 git -C exact-oid-head fetch --no-tags origin \ 720 $commit:refs/heads/exact && 721 test_grep ! command=ls-refs log 722' 723 724test_expect_success 'fetch supports various ways of have lines' ' 725 rm -rf server client trace && 726 git init server && 727 test_commit -C server dwim && 728 TREE=$(git -C server rev-parse HEAD^{tree}) && 729 git -C server tag exact \ 730 $(git -C server commit-tree -m a "$TREE") && 731 git -C server tag dwim-unwanted \ 732 $(git -C server commit-tree -m b "$TREE") && 733 git -C server tag exact-unwanted \ 734 $(git -C server commit-tree -m c "$TREE") && 735 git -C server tag prefix1 \ 736 $(git -C server commit-tree -m d "$TREE") && 737 git -C server tag prefix2 \ 738 $(git -C server commit-tree -m e "$TREE") && 739 git -C server tag fetch-by-sha1 \ 740 $(git -C server commit-tree -m f "$TREE") && 741 git -C server tag completely-unrelated \ 742 $(git -C server commit-tree -m g "$TREE") && 743 744 git init client && 745 GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \ 746 fetch "file://$(pwd)/server" \ 747 dwim \ 748 refs/tags/exact \ 749 refs/tags/prefix*:refs/tags/prefix* \ 750 "$(git -C server rev-parse fetch-by-sha1)" && 751 752 # Ensure that the appropriate prefixes are sent (using a sample) 753 grep "fetch> ref-prefix dwim" trace && 754 grep "fetch> ref-prefix refs/heads/dwim" trace && 755 grep "fetch> ref-prefix refs/tags/prefix" trace && 756 757 # Ensure that the correct objects are returned 758 git -C client cat-file -e $(git -C server rev-parse dwim) && 759 git -C client cat-file -e $(git -C server rev-parse exact) && 760 git -C client cat-file -e $(git -C server rev-parse prefix1) && 761 git -C client cat-file -e $(git -C server rev-parse prefix2) && 762 git -C client cat-file -e $(git -C server rev-parse fetch-by-sha1) && 763 test_must_fail git -C client cat-file -e \ 764 $(git -C server rev-parse dwim-unwanted) && 765 test_must_fail git -C client cat-file -e \ 766 $(git -C server rev-parse exact-unwanted) && 767 test_must_fail git -C client cat-file -e \ 768 $(git -C server rev-parse completely-unrelated) 769' 770 771test_expect_success 'fetch supports include-tag and tag following' ' 772 rm -rf server client trace && 773 git init server && 774 775 test_commit -C server to_fetch && 776 git -C server tag -a annotated_tag -m message && 777 778 git init client && 779 GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \ 780 fetch "$(pwd)/server" to_fetch:to_fetch && 781 782 grep "fetch> ref-prefix to_fetch" trace && 783 grep "fetch> ref-prefix refs/tags/" trace && 784 grep "fetch> include-tag" trace && 785 786 git -C client cat-file -e $(git -C client rev-parse annotated_tag) 787' 788 789test_expect_success 'upload-pack respects client shallows' ' 790 rm -rf server client trace && 791 792 git init server && 793 test_commit -C server base && 794 test_commit -C server client_has && 795 796 git clone --depth=1 "file://$(pwd)/server" client && 797 798 # Add extra commits to the client so that the whole fetch takes more 799 # than 1 request (due to negotiation) 800 test_commit_bulk -C client --id=c 32 && 801 802 git -C server checkout -b newbranch base && 803 test_commit -C server client_wants && 804 805 GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \ 806 fetch origin newbranch && 807 # Ensure that protocol v2 is used 808 grep "fetch< version 2" trace 809' 810 811test_expect_success 'ensure that multiple fetches in same process from a shallow repo works' ' 812 rm -rf server client trace && 813 814 test_create_repo server && 815 test_commit -C server one && 816 test_commit -C server two && 817 test_commit -C server three && 818 git clone --shallow-exclude two "file://$(pwd)/server" client && 819 820 git -C server tag -a -m "an annotated tag" twotag two && 821 822 # Triggers tag following (thus, 2 fetches in one process) 823 GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \ 824 fetch --shallow-exclude one origin && 825 # Ensure that protocol v2 is used 826 grep "fetch< version 2" trace 827' 828 829test_expect_success 'deepen-relative' ' 830 rm -rf server client trace && 831 832 test_create_repo server && 833 test_commit -C server one && 834 test_commit -C server two && 835 test_commit -C server three && 836 git clone --depth 1 "file://$(pwd)/server" client && 837 test_commit -C server four && 838 839 # Sanity check that only "three" is downloaded 840 git -C client log --pretty=tformat:%s main >actual && 841 echo three >expected && 842 test_cmp expected actual && 843 844 GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \ 845 fetch --deepen=1 origin && 846 # Ensure that protocol v2 is used 847 grep "fetch< version 2" trace && 848 849 git -C client log --pretty=tformat:%s origin/main >actual && 850 cat >expected <<-\EOF && 851 four 852 three 853 two 854 EOF 855 test_cmp expected actual 856' 857 858setup_negotiate_only () { 859 SERVER="$1" 860 URI="$2" 861 862 rm -rf "$SERVER" client 863 864 git init "$SERVER" 865 test_commit -C "$SERVER" one 866 test_commit -C "$SERVER" two 867 868 git clone "$URI" client 869 test_commit -C client three 870} 871 872test_expect_success 'usage: --negotiate-only without --negotiation-tip' ' 873 SERVER="server" && 874 URI="file://$(pwd)/server" && 875 876 setup_negotiate_only "$SERVER" "$URI" && 877 878 cat >err.expect <<-\EOF && 879 fatal: --negotiate-only needs one or more --negotiation-tip=* 880 EOF 881 882 test_must_fail git -c protocol.version=2 -C client fetch \ 883 --negotiate-only \ 884 origin 2>err.actual && 885 test_cmp err.expect err.actual 886' 887 888test_expect_success 'usage: --negotiate-only with --recurse-submodules' ' 889 cat >err.expect <<-\EOF && 890 fatal: options '\''--negotiate-only'\'' and '\''--recurse-submodules'\'' cannot be used together 891 EOF 892 893 test_must_fail git -c protocol.version=2 -C client fetch \ 894 --negotiate-only \ 895 --recurse-submodules \ 896 origin 2>err.actual && 897 test_cmp err.expect err.actual 898' 899 900test_expect_success 'file:// --negotiate-only' ' 901 SERVER="server" && 902 URI="file://$(pwd)/server" && 903 904 setup_negotiate_only "$SERVER" "$URI" && 905 906 git -c protocol.version=2 -C client fetch \ 907 --no-tags \ 908 --negotiate-only \ 909 --negotiation-tip=$(git -C client rev-parse HEAD) \ 910 origin >out && 911 COMMON=$(git -C "$SERVER" rev-parse two) && 912 grep "$COMMON" out 913' 914 915test_expect_success 'file:// --negotiate-only with protocol v0' ' 916 SERVER="server" && 917 URI="file://$(pwd)/server" && 918 919 setup_negotiate_only "$SERVER" "$URI" && 920 921 test_must_fail git -c protocol.version=0 -C client fetch \ 922 --no-tags \ 923 --negotiate-only \ 924 --negotiation-tip=$(git -C client rev-parse HEAD) \ 925 origin 2>err && 926 test_grep "negotiate-only requires protocol v2" err 927' 928 929test_expect_success 'push with custom path does not request v2' ' 930 rm -f env.trace && 931 git -C client push \ 932 --receive-pack="env >../env.trace; git-receive-pack" \ 933 origin HEAD:refs/heads/custom-push-test && 934 test_path_is_file env.trace && 935 ! grep ^GIT_PROTOCOL env.trace 936' 937 938test_expect_success 'fetch with custom path does request v2' ' 939 rm -f env.trace && 940 git -C client fetch \ 941 --upload-pack="env >../env.trace; git-upload-pack" \ 942 origin HEAD && 943 grep ^GIT_PROTOCOL=version=2 env.trace 944' 945 946test_expect_success 'archive with custom path does not request v2' ' 947 rm -f env.trace && 948 git -C client archive \ 949 --exec="env >../env.trace; git-upload-archive" \ 950 --remote=origin \ 951 HEAD >/dev/null && 952 test_path_is_file env.trace && 953 ! grep ^GIT_PROTOCOL env.trace 954' 955 956test_expect_success 'reject client packfile-uris if not advertised' ' 957 { 958 packetize command=fetch && 959 packetize object-format=$(test_oid algo) && 960 printf 0001 && 961 packetize packfile-uris https && 962 packetize done && 963 printf 0000 964 } >input && 965 test_must_fail env GIT_PROTOCOL=version=2 \ 966 git upload-pack client <input && 967 test_must_fail env GIT_PROTOCOL=version=2 \ 968 git -c uploadpack.blobpackfileuri \ 969 upload-pack client <input && 970 GIT_PROTOCOL=version=2 \ 971 git -c uploadpack.blobpackfileuri=anything \ 972 upload-pack client <input 973' 974 975# Test protocol v2 with 'http://' transport 976# 977. "$TEST_DIRECTORY"/lib-httpd.sh 978start_httpd 979 980test_expect_success 'create repo to be served by http:// transport' ' 981 git init "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && 982 git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" config http.receivepack true && 983 test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one 984' 985 986test_expect_success 'clone with http:// using protocol v2' ' 987 test_when_finished "rm -f log" && 988 989 GIT_TRACE_PACKET="$(pwd)/log" GIT_TRACE_CURL="$(pwd)/log" git -c protocol.version=2 \ 990 clone "$HTTPD_URL/smart/http_parent" http_child && 991 992 git -C http_child log -1 --format=%s >actual && 993 git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect && 994 test_cmp expect actual && 995 996 # Client requested to use protocol v2 997 grep "Git-Protocol: version=2" log && 998 # Server responded using protocol v2 999 grep "git< version 2" log && 1000 # Verify that the chunked encoding sending codepath is NOT exercised 1001 ! grep "Send header: Transfer-Encoding: chunked" log 1002' 1003 1004test_expect_success 'clone repository with http:// using protocol v2 with incomplete pktline length' ' 1005 test_when_finished "rm -f log" && 1006 1007 git init "$HTTPD_DOCUMENT_ROOT_PATH/incomplete_length" && 1008 test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/incomplete_length" file && 1009 1010 test_must_fail env GIT_TRACE_PACKET="$(pwd)/log" GIT_TRACE_CURL="$(pwd)/log" git -c protocol.version=2 \ 1011 clone "$HTTPD_URL/smart/incomplete_length" incomplete_length_child 2>err && 1012 1013 # Client requested to use protocol v2 1014 grep "Git-Protocol: version=2" log && 1015 # Server responded using protocol v2 1016 grep "git< version 2" log && 1017 # Client reported appropriate failure 1018 test_grep "bytes of length header were received" err 1019' 1020 1021test_expect_success 'clone repository with http:// using protocol v2 with incomplete pktline body' ' 1022 test_when_finished "rm -f log" && 1023 1024 git init "$HTTPD_DOCUMENT_ROOT_PATH/incomplete_body" && 1025 test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/incomplete_body" file && 1026 1027 test_must_fail env GIT_TRACE_PACKET="$(pwd)/log" GIT_TRACE_CURL="$(pwd)/log" git -c protocol.version=2 \ 1028 clone "$HTTPD_URL/smart/incomplete_body" incomplete_body_child 2>err && 1029 1030 # Client requested to use protocol v2 1031 grep "Git-Protocol: version=2" log && 1032 # Server responded using protocol v2 1033 grep "git< version 2" log && 1034 # Client reported appropriate failure 1035 test_grep "bytes of body are still expected" err 1036' 1037 1038test_expect_success 'clone with http:// using protocol v2 and invalid parameters' ' 1039 test_when_finished "rm -f log" && 1040 1041 test_must_fail env GIT_TRACE_PACKET="$(pwd)/log" GIT_TRACE_CURL="$(pwd)/log" \ 1042 git -c protocol.version=2 \ 1043 clone --shallow-since=20151012 "$HTTPD_URL/smart/http_parent" http_child_invalid && 1044 1045 # Client requested to use protocol v2 1046 grep "Git-Protocol: version=2" log && 1047 # Server responded using protocol v2 1048 grep "git< version 2" log 1049' 1050 1051test_expect_success 'clone big repository with http:// using protocol v2' ' 1052 test_when_finished "rm -f log" && 1053 1054 git init "$HTTPD_DOCUMENT_ROOT_PATH/big" && 1055 # Ensure that the list of wants is greater than http.postbuffer below 1056 for i in $(test_seq 1 1500) 1057 do 1058 # do not use here-doc, because it requires a process 1059 # per loop iteration 1060 echo "commit refs/heads/too-many-refs-$i" && 1061 echo "committer git <git@example.com> $i +0000" && 1062 echo "data 0" && 1063 echo "M 644 inline bla.txt" && 1064 echo "data 4" && 1065 echo "bla" || return 1 1066 done | git -C "$HTTPD_DOCUMENT_ROOT_PATH/big" fast-import && 1067 1068 GIT_TRACE_PACKET="$(pwd)/log" GIT_TRACE_CURL="$(pwd)/log" git \ 1069 -c protocol.version=2 -c http.postbuffer=65536 \ 1070 clone "$HTTPD_URL/smart/big" big_child && 1071 1072 # Client requested to use protocol v2 1073 grep "Git-Protocol: version=2" log && 1074 # Server responded using protocol v2 1075 grep "git< version 2" log && 1076 # Verify that the chunked encoding sending codepath is exercised 1077 grep "Send header: Transfer-Encoding: chunked" log 1078' 1079 1080test_expect_success 'fetch with http:// using protocol v2' ' 1081 test_when_finished "rm -f log" && 1082 1083 test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two && 1084 1085 GIT_TRACE_PACKET="$(pwd)/log" git -C http_child -c protocol.version=2 \ 1086 fetch && 1087 1088 git -C http_child log -1 --format=%s origin/main >actual && 1089 git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect && 1090 test_cmp expect actual && 1091 1092 # Server responded using protocol v2 1093 grep "git< version 2" log 1094' 1095 1096test_expect_success 'fetch with http:// by hash without tag following with protocol v2 does not list refs' ' 1097 test_when_finished "rm -f log" && 1098 1099 test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two_a && 1100 git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" rev-parse two_a >two_a_hash && 1101 1102 GIT_TRACE_PACKET="$(pwd)/log" git -C http_child -c protocol.version=2 \ 1103 fetch --no-tags origin $(cat two_a_hash) && 1104 1105 grep "fetch< version 2" log && 1106 ! grep "fetch> command=ls-refs" log 1107' 1108 1109test_expect_success 'fetch from namespaced repo respects namespaces' ' 1110 test_when_finished "rm -f log" && 1111 1112 git init "$HTTPD_DOCUMENT_ROOT_PATH/nsrepo" && 1113 test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/nsrepo" one && 1114 test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/nsrepo" two && 1115 git -C "$HTTPD_DOCUMENT_ROOT_PATH/nsrepo" \ 1116 update-ref refs/namespaces/ns/refs/heads/main one && 1117 1118 GIT_TRACE_PACKET="$(pwd)/log" git -C http_child -c protocol.version=2 \ 1119 fetch "$HTTPD_URL/smart_namespace/nsrepo" \ 1120 refs/heads/main:refs/heads/theirs && 1121 1122 # Server responded using protocol v2 1123 grep "fetch< version 2" log && 1124 1125 git -C "$HTTPD_DOCUMENT_ROOT_PATH/nsrepo" rev-parse one >expect && 1126 git -C http_child rev-parse theirs >actual && 1127 test_cmp expect actual 1128' 1129 1130test_expect_success 'ls-remote with v2 http sends only one POST' ' 1131 test_when_finished "rm -f log" && 1132 1133 git ls-remote "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" >expect && 1134 GIT_TRACE_CURL="$(pwd)/log" git -c protocol.version=2 \ 1135 ls-remote "$HTTPD_URL/smart/http_parent" >actual && 1136 test_cmp expect actual && 1137 1138 grep "Send header: POST" log >posts && 1139 test_line_count = 1 posts 1140' 1141 1142test_expect_success 'push with http:// and a config of v2 does not request v2' ' 1143 test_when_finished "rm -f log" && 1144 # Till v2 for push is designed, make sure that if a client has 1145 # protocol.version configured to use v2, that the client instead falls 1146 # back and uses v0. 1147 1148 test_commit -C http_child three && 1149 1150 # Push to another branch, as the target repository has the 1151 # main branch checked out and we cannot push into it. 1152 GIT_TRACE_PACKET="$(pwd)/log" git -C http_child -c protocol.version=2 \ 1153 push origin HEAD:client_branch && 1154 1155 git -C http_child log -1 --format=%s >actual && 1156 git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s client_branch >expect && 1157 test_cmp expect actual && 1158 1159 # Client did not request to use protocol v2 1160 ! grep "Git-Protocol: version=2" log && 1161 # Server did not respond using protocol v2 1162 ! grep "git< version 2" log 1163' 1164 1165test_expect_success 'when server sends "ready", expect DELIM' ' 1166 rm -rf "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" http_child && 1167 1168 git init "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && 1169 test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one && 1170 1171 git clone "$HTTPD_URL/smart/http_parent" http_child && 1172 1173 test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two && 1174 1175 # After "ready" in the acknowledgments section, pretend that a FLUSH 1176 # (0000) was sent instead of a DELIM (0001). 1177 write_script "$HTTPD_ROOT_PATH/one-time-script" <<-\EOF && 1178 sed "/ready/{n;s/0001/0000/;}" "$1" 1179 EOF 1180 1181 test_must_fail git -C http_child -c protocol.version=2 \ 1182 fetch "$HTTPD_URL/one_time_script/http_parent" 2> err && 1183 test_grep "expected packfile to be sent after .ready." err 1184' 1185 1186test_expect_success 'when server does not send "ready", expect FLUSH' ' 1187 rm -rf "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" http_child log && 1188 1189 git init "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && 1190 test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one && 1191 1192 git clone "$HTTPD_URL/smart/http_parent" http_child && 1193 1194 test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two && 1195 1196 # Create many commits to extend the negotiation phase across multiple 1197 # requests, so that the server does not send "ready" in the first 1198 # request. 1199 test_commit_bulk -C http_child --id=c 32 && 1200 1201 # After the acknowledgments section, pretend that a DELIM 1202 # (0001) was sent instead of a FLUSH (0000). 1203 write_script "$HTTPD_ROOT_PATH/one-time-script" <<-\EOF && 1204 sed "/acknowledgments/,//{s/0000/0001/;}" "$1" 1205 EOF 1206 1207 test_must_fail env GIT_TRACE_PACKET="$(pwd)/log" git -C http_child \ 1208 -c protocol.version=2 \ 1209 fetch "$HTTPD_URL/one_time_script/http_parent" 2> err && 1210 grep "fetch< .*acknowledgments" log && 1211 ! grep "fetch< .*ready" log && 1212 test_grep "expected no other sections to be sent after no .ready." err 1213' 1214 1215configure_exclusion () { 1216 git -C "$1" hash-object "$2" >objh && 1217 git -C "$1" pack-objects "$HTTPD_DOCUMENT_ROOT_PATH/mypack" <objh >packh && 1218 git -C "$1" config --add \ 1219 "uploadpack.blobpackfileuri" \ 1220 "$(cat objh) $(cat packh) $HTTPD_URL/dumb/mypack-$(cat packh).pack" && 1221 cat objh 1222} 1223 1224test_expect_success 'part of packfile response provided as URI' ' 1225 P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && 1226 rm -rf "$P" http_child log && 1227 1228 git init "$P" && 1229 git -C "$P" config "uploadpack.allowsidebandall" "true" && 1230 1231 echo my-blob >"$P/my-blob" && 1232 git -C "$P" add my-blob && 1233 echo other-blob >"$P/other-blob" && 1234 git -C "$P" add other-blob && 1235 git -C "$P" commit -m x && 1236 1237 configure_exclusion "$P" my-blob >h && 1238 configure_exclusion "$P" other-blob >h2 && 1239 1240 GIT_TRACE=1 GIT_TRACE_PACKET="$(pwd)/log" GIT_TEST_SIDEBAND_ALL=1 \ 1241 git -c protocol.version=2 \ 1242 -c fetch.uriprotocols=http,https \ 1243 clone "$HTTPD_URL/smart/http_parent" http_child && 1244 1245 # Ensure that my-blob and other-blob are in separate packfiles. 1246 for idx in http_child/.git/objects/pack/*.idx 1247 do 1248 git verify-pack --object-format=$(test_oid algo) --verbose $idx >out && 1249 { 1250 grep -E "^[0-9a-f]{16,} " out || : 1251 } >out.objectlist && 1252 if test_line_count = 1 out.objectlist 1253 then 1254 if grep $(cat h) out 1255 then 1256 >hfound 1257 fi && 1258 if grep $(cat h2) out 1259 then 1260 >h2found 1261 fi 1262 fi || return 1 1263 done && 1264 test -f hfound && 1265 test -f h2found && 1266 1267 # Ensure that there are exactly 3 packfiles with associated .idx 1268 ls http_child/.git/objects/pack/*.pack \ 1269 http_child/.git/objects/pack/*.idx >filelist && 1270 test_line_count = 6 filelist 1271' 1272 1273test_expect_success 'packfile URIs with fetch instead of clone' ' 1274 P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && 1275 rm -rf "$P" http_child log && 1276 1277 git init "$P" && 1278 git -C "$P" config "uploadpack.allowsidebandall" "true" && 1279 1280 echo my-blob >"$P/my-blob" && 1281 git -C "$P" add my-blob && 1282 git -C "$P" commit -m x && 1283 1284 configure_exclusion "$P" my-blob >h && 1285 1286 git init http_child && 1287 1288 GIT_TEST_SIDEBAND_ALL=1 \ 1289 git -C http_child -c protocol.version=2 \ 1290 -c fetch.uriprotocols=http,https \ 1291 fetch "$HTTPD_URL/smart/http_parent" 1292' 1293 1294test_expect_success 'fetching with valid packfile URI but invalid hash fails' ' 1295 P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && 1296 rm -rf "$P" http_child log && 1297 1298 git init "$P" && 1299 git -C "$P" config "uploadpack.allowsidebandall" "true" && 1300 1301 echo my-blob >"$P/my-blob" && 1302 git -C "$P" add my-blob && 1303 echo other-blob >"$P/other-blob" && 1304 git -C "$P" add other-blob && 1305 git -C "$P" commit -m x && 1306 1307 configure_exclusion "$P" my-blob >h && 1308 # Configure a URL for other-blob. Just reuse the hash of the object as 1309 # the hash of the packfile, since the hash does not matter for this 1310 # test as long as it is not the hash of the pack, and it is of the 1311 # expected length. 1312 git -C "$P" hash-object other-blob >objh && 1313 git -C "$P" pack-objects "$HTTPD_DOCUMENT_ROOT_PATH/mypack" <objh >packh && 1314 git -C "$P" config --add \ 1315 "uploadpack.blobpackfileuri" \ 1316 "$(cat objh) $(cat objh) $HTTPD_URL/dumb/mypack-$(cat packh).pack" && 1317 1318 test_must_fail env GIT_TEST_SIDEBAND_ALL=1 \ 1319 git -c protocol.version=2 \ 1320 -c fetch.uriprotocols=http,https \ 1321 clone "$HTTPD_URL/smart/http_parent" http_child 2>err && 1322 test_grep "pack downloaded from.*does not match expected hash" err 1323' 1324 1325test_expect_success 'packfile-uri with transfer.fsckobjects' ' 1326 P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && 1327 rm -rf "$P" http_child log && 1328 1329 git init "$P" && 1330 git -C "$P" config "uploadpack.allowsidebandall" "true" && 1331 1332 echo my-blob >"$P/my-blob" && 1333 git -C "$P" add my-blob && 1334 git -C "$P" commit -m x && 1335 1336 configure_exclusion "$P" my-blob >h && 1337 1338 sane_unset GIT_TEST_SIDEBAND_ALL && 1339 git -c protocol.version=2 -c transfer.fsckobjects=1 \ 1340 -c fetch.uriprotocols=http,https \ 1341 clone "$HTTPD_URL/smart/http_parent" http_child && 1342 1343 # Ensure that there are exactly 2 packfiles with associated .idx 1344 ls http_child/.git/objects/pack/*.pack \ 1345 http_child/.git/objects/pack/*.idx >filelist && 1346 test_line_count = 4 filelist 1347' 1348 1349test_expect_success 'packfile-uri with transfer.fsckobjects fails on bad object' ' 1350 P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && 1351 rm -rf "$P" http_child log && 1352 1353 git init "$P" && 1354 git -C "$P" config "uploadpack.allowsidebandall" "true" && 1355 1356 cat >bogus-commit <<-EOF && 1357 tree $EMPTY_TREE 1358 author Bugs Bunny 1234567890 +0000 1359 committer Bugs Bunny <bugs@bun.ni> 1234567890 +0000 1360 1361 This commit object intentionally broken 1362 EOF 1363 BOGUS=$(git -C "$P" hash-object -t commit -w --stdin --literally <bogus-commit) && 1364 git -C "$P" branch bogus-branch "$BOGUS" && 1365 1366 echo my-blob >"$P/my-blob" && 1367 git -C "$P" add my-blob && 1368 git -C "$P" commit -m x && 1369 1370 configure_exclusion "$P" my-blob >h && 1371 1372 sane_unset GIT_TEST_SIDEBAND_ALL && 1373 test_must_fail git -c protocol.version=2 -c transfer.fsckobjects=1 \ 1374 -c fetch.uriprotocols=http,https \ 1375 clone "$HTTPD_URL/smart/http_parent" http_child 2>error && 1376 test_grep "invalid author/committer line - missing email" error 1377' 1378 1379test_expect_success 'packfile-uri with transfer.fsckobjects succeeds when .gitmodules is separate from tree' ' 1380 P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && 1381 rm -rf "$P" http_child && 1382 1383 git init "$P" && 1384 git -C "$P" config "uploadpack.allowsidebandall" "true" && 1385 1386 echo "[submodule libfoo]" >"$P/.gitmodules" && 1387 echo "path = include/foo" >>"$P/.gitmodules" && 1388 echo "url = git://example.com/git/lib.git" >>"$P/.gitmodules" && 1389 git -C "$P" add .gitmodules && 1390 git -C "$P" commit -m x && 1391 1392 configure_exclusion "$P" .gitmodules >h && 1393 1394 sane_unset GIT_TEST_SIDEBAND_ALL && 1395 git -c protocol.version=2 -c transfer.fsckobjects=1 \ 1396 -c fetch.uriprotocols=http,https \ 1397 clone "$HTTPD_URL/smart/http_parent" http_child && 1398 1399 # Ensure that there are exactly 2 packfiles with associated .idx 1400 ls http_child/.git/objects/pack/*.pack \ 1401 http_child/.git/objects/pack/*.idx >filelist && 1402 test_line_count = 4 filelist 1403' 1404 1405test_expect_success 'packfile-uri with transfer.fsckobjects fails when .gitmodules separate from tree is invalid' ' 1406 P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && 1407 rm -rf "$P" http_child err && 1408 1409 git init "$P" && 1410 git -C "$P" config "uploadpack.allowsidebandall" "true" && 1411 1412 echo "[submodule \"..\"]" >"$P/.gitmodules" && 1413 echo "path = include/foo" >>"$P/.gitmodules" && 1414 echo "url = git://example.com/git/lib.git" >>"$P/.gitmodules" && 1415 git -C "$P" add .gitmodules && 1416 git -C "$P" commit -m x && 1417 1418 configure_exclusion "$P" .gitmodules >h && 1419 1420 sane_unset GIT_TEST_SIDEBAND_ALL && 1421 test_must_fail git -c protocol.version=2 -c transfer.fsckobjects=1 \ 1422 -c fetch.uriprotocols=http,https \ 1423 clone "$HTTPD_URL/smart/http_parent" http_child 2>err && 1424 test_grep "disallowed submodule name" err 1425' 1426 1427test_expect_success 'packfile-uri path redacted in trace' ' 1428 P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && 1429 rm -rf "$P" http_child log && 1430 1431 git init "$P" && 1432 git -C "$P" config "uploadpack.allowsidebandall" "true" && 1433 1434 echo my-blob >"$P/my-blob" && 1435 git -C "$P" add my-blob && 1436 git -C "$P" commit -m x && 1437 1438 git -C "$P" hash-object my-blob >objh && 1439 git -C "$P" pack-objects "$HTTPD_DOCUMENT_ROOT_PATH/mypack" <objh >packh && 1440 git -C "$P" config --add \ 1441 "uploadpack.blobpackfileuri" \ 1442 "$(cat objh) $(cat packh) $HTTPD_URL/dumb/mypack-$(cat packh).pack" && 1443 1444 GIT_TRACE_PACKET="$(pwd)/log" \ 1445 git -c protocol.version=2 \ 1446 -c fetch.uriprotocols=http,https \ 1447 clone "$HTTPD_URL/smart/http_parent" http_child && 1448 1449 grep -F "clone< \\1$(cat packh) $HTTPD_URL/<redacted>" log 1450' 1451 1452test_expect_success 'packfile-uri path not redacted in trace when GIT_TRACE_REDACT=0' ' 1453 P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && 1454 rm -rf "$P" http_child log && 1455 1456 git init "$P" && 1457 git -C "$P" config "uploadpack.allowsidebandall" "true" && 1458 1459 echo my-blob >"$P/my-blob" && 1460 git -C "$P" add my-blob && 1461 git -C "$P" commit -m x && 1462 1463 git -C "$P" hash-object my-blob >objh && 1464 git -C "$P" pack-objects "$HTTPD_DOCUMENT_ROOT_PATH/mypack" <objh >packh && 1465 git -C "$P" config --add \ 1466 "uploadpack.blobpackfileuri" \ 1467 "$(cat objh) $(cat packh) $HTTPD_URL/dumb/mypack-$(cat packh).pack" && 1468 1469 GIT_TRACE_PACKET="$(pwd)/log" \ 1470 GIT_TRACE_REDACT=0 \ 1471 git -c protocol.version=2 \ 1472 -c fetch.uriprotocols=http,https \ 1473 clone "$HTTPD_URL/smart/http_parent" http_child && 1474 1475 grep -F "clone< \\1$(cat packh) $HTTPD_URL/dumb/mypack-$(cat packh).pack" log 1476' 1477 1478test_expect_success 'http:// --negotiate-only' ' 1479 SERVER="$HTTPD_DOCUMENT_ROOT_PATH/server" && 1480 URI="$HTTPD_URL/smart/server" && 1481 1482 setup_negotiate_only "$SERVER" "$URI" && 1483 1484 git -c protocol.version=2 -C client fetch \ 1485 --no-tags \ 1486 --negotiate-only \ 1487 --negotiation-tip=$(git -C client rev-parse HEAD) \ 1488 origin >out && 1489 COMMON=$(git -C "$SERVER" rev-parse two) && 1490 grep "$COMMON" out 1491' 1492 1493test_expect_success 'http:// --negotiate-only without wait-for-done support' ' 1494 SERVER="server" && 1495 URI="$HTTPD_URL/one_time_script/server" && 1496 1497 setup_negotiate_only "$SERVER" "$URI" && 1498 1499 write_script "$HTTPD_ROOT_PATH/one-time-script" <<-\EOF && 1500 sed "s/ wait-for-done/ xxxx-xxx-xxxx/" "$1" 1501 EOF 1502 1503 test_must_fail git -c protocol.version=2 -C client fetch \ 1504 --no-tags \ 1505 --negotiate-only \ 1506 --negotiation-tip=$(git -C client rev-parse HEAD) \ 1507 origin 2>err && 1508 test_grep "server does not support wait-for-done" err 1509' 1510 1511test_expect_success 'http:// --negotiate-only with protocol v0' ' 1512 SERVER="$HTTPD_DOCUMENT_ROOT_PATH/server" && 1513 URI="$HTTPD_URL/smart/server" && 1514 1515 setup_negotiate_only "$SERVER" "$URI" && 1516 1517 test_must_fail git -c protocol.version=0 -C client fetch \ 1518 --no-tags \ 1519 --negotiate-only \ 1520 --negotiation-tip=$(git -C client rev-parse HEAD) \ 1521 origin 2>err && 1522 test_grep "negotiate-only requires protocol v2" err 1523' 1524 1525# DO NOT add non-httpd-specific tests here, because the last part of this 1526# test script is only executed when httpd is available and enabled. 1527 1528test_done