(CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <'test fetching over git protocol'>)} spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (C {(.)} {(DQ ($ VSub_Name '$TEST_DIRECTORY')) (/lib-git-daemon.sh)}) (C {(start_git_daemon)}) (FuncDef name: check_verbose_connect body: (BraceGroup children: [ (AndOr ops: [Op_DAmp Op_DAmp] children: [ (C {(grep)} {(-F)} {(DQ ('Looking up 127.0.0.1 ...'))} {(stderr)}) (C {(grep)} {(-F)} {(DQ ('Connecting to 127.0.0.1 (port '))} {(stderr)}) (C {(grep)} {(-F)} {(DQ (done.))} {(stderr)}) ] ) ] spids: [29] ) spids: [24 28] ) (C {(test_expect_success)} {(SQ <'setup repository'>)} { (SQ <'\n'> <'\tgit config push.default matching &&\n'> <'\techo content >file &&\n'> <'\tgit add file &&\n'> <'\tgit commit -m one\n'> ) } ) (C {(test_expect_success)} {(SQ <'create git-accessible bare repository'>)} { (SQ <'\n'> <'\tmkdir "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&\n'> <'\t(cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&\n'> <'\t git --bare init &&\n'> <'\t : >git-daemon-export-ok\n'> <'\t) &&\n'> <'\tgit remote add public "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&\n'> <'\tgit push public master:master\n'> ) } ) (C {(test_expect_success)} {(SQ <'clone git repository'>)} { (SQ <'\n'> <'\tgit clone -v "$GIT_DAEMON_URL/repo.git" clone 2>stderr &&\n'> <'\tcheck_verbose_connect &&\n'> <'\ttest_cmp file clone/file\n'> ) } ) (C {(test_expect_success)} {(SQ <'fetch changes via git protocol'>)} { (SQ <'\n'> <'\techo content >>file &&\n'> <'\tgit commit -a -m two &&\n'> <'\tgit push public &&\n'> <'\t(cd clone && git pull -v) 2>stderr &&\n'> <'\tcheck_verbose_connect &&\n'> <'\ttest_cmp file clone/file\n'> ) } ) (C {(test_expect_success)} {(SQ <'no-op fetch -v stderr is as expected'>)} {(SQ <'\n'> <'\t(cd clone && git fetch -v) 2>stderr &&\n'> <'\tcheck_verbose_connect\n'>)} ) (C {(test_expect_success)} {(SQ <'no-op fetch without "-v" is quiet'>)} {(SQ <'\n'> <'\t(cd clone && git fetch) 2>stderr &&\n'> <'\t! test -s stderr\n'>)} ) (C {(test_expect_success)} {(SQ <'remote detects correct HEAD'>)} { (SQ <'\n'> <'\tgit push public master:other &&\n'> <'\t(cd clone &&\n'> <'\t git remote set-head -d origin &&\n'> <'\t git remote set-head -a origin &&\n'> <'\t git symbolic-ref refs/remotes/origin/HEAD > output &&\n'> <'\t echo refs/remotes/origin/master > expect &&\n'> <'\t test_cmp expect output\n'> <'\t)\n'> ) } ) (C {(test_expect_success)} {(SQ <'prepare pack objects'>)} { (SQ <'\n'> < '\tcp -R "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo.git "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git &&\n' > <'\t(cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git &&\n'> <'\t git --bare repack -a -d\n'> <'\t)\n'> ) } ) (C {(test_expect_success)} {(SQ <'fetch notices corrupt pack'>)} { (SQ <'\n'> < '\tcp -R "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad1.git &&\n' > <'\t(cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad1.git &&\n'> <'\t p=$(ls objects/pack/pack-*.pack) &&\n'> <'\t chmod u+w $p &&\n'> <'\t printf %0256d 0 | dd of=$p bs=256 count=1 seek=1 conv=notrunc\n'> <'\t) &&\n'> <'\tmkdir repo_bad1.git &&\n'> <'\t(cd repo_bad1.git &&\n'> <'\t git --bare init &&\n'> <'\t test_must_fail git --bare fetch "$GIT_DAEMON_URL/repo_bad1.git" &&\n'> <'\t test 0 = $(ls objects/pack/pack-*.pack | wc -l)\n'> <'\t)\n'> ) } ) (C {(test_expect_success)} {(SQ <'fetch notices corrupt idx'>)} { (SQ <'\n'> < '\tcp -R "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad2.git &&\n' > <'\t(cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad2.git &&\n'> <'\t p=$(ls objects/pack/pack-*.idx) &&\n'> <'\t chmod u+w $p &&\n'> <'\t printf %0256d 0 | dd of=$p bs=256 count=1 seek=1 conv=notrunc\n'> <'\t) &&\n'> <'\tmkdir repo_bad2.git &&\n'> <'\t(cd repo_bad2.git &&\n'> <'\t git --bare init &&\n'> <'\t test_must_fail git --bare fetch "$GIT_DAEMON_URL/repo_bad2.git" &&\n'> <'\t test 0 = $(ls objects/pack | wc -l)\n'> <'\t)\n'> ) } ) (FuncDef name: test_remote_error body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:do_export) op: Equal rhs: {(YesPlease)} spids: [248] ) ] spids: [248] ) (While cond: [(C {(test)} {($ VSub_Pound '$#')} {(-gt)} {(0)})] body: (DoGroup children: [ (Case to_match: {($ VSub_Number '$1')} arms: [ (case_arm pat_list: [{(-x)}] action: [ (C {(shift)}) (C {(chmod)} {(-x)} {(DQ ($ VSub_Name '$GIT_DAEMON_DOCUMENT_ROOT_PATH') (/repo.git))} ) ] spids: [273 274 290 16777215] ) (case_arm pat_list: [{(-n)}] action: [ (C {(shift)}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:do_export) op: Equal rhs: {(EmptyPart)} spids: [300] ) ] spids: [300] ) ] spids: [293 294 303 16777215] ) (case_arm pat_list: [{(Lit_Other '*')}] action: [(ControlFlow token:<ControlFlow_Break break>)] spids: [306 307 16777215 313] ) ] spids: [266 270 313] ) ] spids: [263 316] ) ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:msg) op: Equal rhs: {($ VSub_Number '$1')} spids: [320] ) ] spids: [320] ) (C {(shift)}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:cmd) op: Equal rhs: {($ VSub_Number '$1')} spids: [327] ) ] spids: [327] ) (C {(shift)}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:repo) op: Equal rhs: {($ VSub_Number '$1')} spids: [334] ) ] spids: [334] ) (AndOr ops: [Op_DPipe] children: [(C {(shift)}) (C {(error)} {(DQ ('invalid number of arguments'))})] ) (If arms: [ (if_arm cond: [ (C {(test)} {(-x)} {(DQ ($ VSub_Name '$GIT_DAEMON_DOCUMENT_ROOT_PATH') (/) ($ VSub_Name '$repo'))} ) ] action: [ (If arms: [ (if_arm cond: [(C {(test)} {(-n)} {(DQ ($ VSub_Name '$do_export'))})] action: [ (SimpleCommand words: [{(Lit_Other ':')}] redirects: [ (Redir op_id: Redir_Great fd: 16777215 arg_word: { (DQ ($ VSub_Name '$GIT_DAEMON_DOCUMENT_ROOT_PATH') (/) ($ VSub_Name '$repo') (/git-daemon-export-ok) ) } spids: [382] ) ] ) ] spids: [16777215 377] ) ] else_action: [ (C {(rm)} {(-f)} { (DQ ($ VSub_Name '$GIT_DAEMON_DOCUMENT_ROOT_PATH') (/) ($ VSub_Name '$repo') (/git-daemon-export-ok) ) } ) ] spids: [391 406] ) ] spids: [16777215 363] ) ] spids: [16777215 409] ) (AndOr ops: [Op_DAmp Op_DAmp] children: [ (SimpleCommand words: [ {(test_must_fail)} {(git)} {(DQ ($ VSub_Name '$cmd'))} {(DQ ($ VSub_Name '$GIT_DAEMON_URL') (/) ($ VSub_Name '$repo'))} {(DQ ($ VSub_At '$@'))} ] redirects: [(Redir op_id:Redir_Great fd:2 arg_word:{(output)} spids:[431])] ) (C {(test_i18ngrep)} {(DQ ('fatal: remote error: ') ($ VSub_Name '$msg') (': /') ($ VSub_Name '$repo'))} {(output)} ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:ret) op: Equal rhs: {($ VSub_QMark '$?')} spids: [451] ) ] spids: [451] ) ] ) (C {(chmod)} {(Lit_Other '+') (x)} {(DQ ($ VSub_Name '$GIT_DAEMON_DOCUMENT_ROOT_PATH') (/repo.git))} ) (Subshell child: (ControlFlow token:<ControlFlow_Exit exit> arg_word:{($ VSub_Name '$ret')}) spids: [466 470] ) ] spids: [245] ) spids: [241 244] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:msg) op: Equal rhs: {(DQ ('access denied or repository not exported'))} spids: [475] ) ] spids: [475] ) (C {(test_expect_success)} {(SQ <'clone non-existent'>)} {(DQ ("test_remote_error '") ($ VSub_Name '$msg') ("' clone nowhere.git "))} ) (C {(test_expect_success)} {(SQ <'push disabled'>)} {(DQ ("test_remote_error '") ($ VSub_Name '$msg') ("' push repo.git master"))} ) (C {(test_expect_success)} {(SQ <'read access denied'>)} {(DQ ("test_remote_error -x '") ($ VSub_Name '$msg') ("' fetch repo.git "))} ) (C {(test_expect_success)} {(SQ <'not exported'>)} {(DQ ("test_remote_error -n '") ($ VSub_Name '$msg') ("' fetch repo.git "))} ) (C {(stop_git_daemon)}) (C {(start_git_daemon)} {(--informative-errors)}) (C {(test_expect_success)} {(SQ <'clone non-existent'>)} {(DQ ("test_remote_error 'no such repository' clone nowhere.git "))} ) (C {(test_expect_success)} {(SQ <'push disabled'>)} {(DQ ("test_remote_error 'service not enabled' push repo.git master"))} ) (C {(test_expect_success)} {(SQ <'read access denied'>)} {(DQ ("test_remote_error -x 'no such repository' fetch repo.git "))} ) (C {(test_expect_success)} {(SQ <'not exported'>)} {(DQ ("test_remote_error -n 'repository not exported' fetch repo.git "))} ) (C {(stop_git_daemon)}) (C {(start_git_daemon)} {(--interpolated-path) (Lit_Other '=') (DQ ($ VSub_Name '$GIT_DAEMON_DOCUMENT_ROOT_PATH') ('/%H%D')) } ) (C {(test_expect_success)} {(SQ <'access repo via interpolated hostname'>)} { (SQ <'\n'> <'\trepo="$GIT_DAEMON_DOCUMENT_ROOT_PATH/localhost/interp.git" &&\n'> <'\tgit init --bare "$repo" &&\n'> <'\tgit push "$repo" HEAD &&\n'> <'\t>"$repo"/git-daemon-export-ok &&\n'> <'\trm -rf tmp.git &&\n'> <'\tGIT_OVERRIDE_VIRTUAL_HOST=localhost \\\n'> <'\t\tgit clone --bare "$GIT_DAEMON_URL/interp.git" tmp.git &&\n'> <'\trm -rf tmp.git &&\n'> <'\tGIT_OVERRIDE_VIRTUAL_HOST=LOCALHOST \\\n'> <'\t\tgit clone --bare "$GIT_DAEMON_URL/interp.git" tmp.git\n'> ) } ) (C {(test_expect_success)} {(SQ <'hostname cannot break out of directory'>)} { (SQ <'\n'> <'\trm -rf tmp.git &&\n'> <'\trepo="$GIT_DAEMON_DOCUMENT_ROOT_PATH/../escape.git" &&\n'> <'\tgit init --bare "$repo" &&\n'> <'\tgit push "$repo" HEAD &&\n'> <'\t>"$repo"/git-daemon-export-ok &&\n'> <'\ttest_must_fail \\\n'> <'\t\tenv GIT_OVERRIDE_VIRTUAL_HOST=.. \\\n'> <'\t\tgit clone --bare "$GIT_DAEMON_URL/escape.git" tmp.git\n'> ) } ) (C {(stop_git_daemon)}) (C {(test_done)}) ] )