(command.CommandList children: [ (command.Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (lhs_expr.LhsName name:test_description) op: Equal rhs: { (SQ <'git archive and git get-tar-commit-id test\n'> <'\n'> <'This test covers the topics of file contents, commit date handling and\n'> <'commit id embedding:\n'> <'\n'> <' The contents of the repository is compared to the extracted tar\n'> <' archive. The repository contains simple text files, symlinks and a\n'> <' binary file (/bin/sh). Only paths shorter than 99 characters are\n'> <' used.\n'> <'\n'> <' git archive applies the commit date to every file in the archive it\n'> <' creates. The test sets the commit date to a specific value and checks\n'> <' if the tar archive contains that value.\n'> <'\n'> <' When giving git archive a commit id (in contrast to a tree id) it\n'> <' embeds this commit id into the tar archive as a comment. The test\n'> <' checks the ability of git get-tar-commit-id to figure it out from the\n'> <' tar file.\n'> <'\n'> ) } ) ] ) (C {(.)} {(./test-lib.sh)}) (command.Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (lhs_expr.LhsName name:SUBSTFORMAT) op: Equal rhs: {(Lit_Other '%') (H) (Lit_Other '%') (n)} ) ] ) (C {(test_lazy_prereq)} {(TAR_NEEDS_PAX_FALLBACK)} { (SQ <'\n'> <'\t(\n'> <'\t\tmkdir pax &&\n'> <'\t\tcd pax &&\n'> <'\t\t"$TAR" xf "$TEST_DIRECTORY"/t5000/pax.tar &&\n'> <'\t\ttest -f PaxHeaders.1791/file\n'> <'\t)\n'> ) } ) (C {(test_lazy_prereq)} {(GZIP)} {(SQ <'gzip --version'>)}) (command.FuncDef name: get_pax_header body: (command.BraceGroup children: [ (command.Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (lhs_expr.LhsName name:file) op: Equal rhs: {($ VSub_Number '$1')} ) ] ) (command.Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (lhs_expr.LhsName name:header) op: Equal rhs: {($ VSub_Number '$2') (Lit_Other '=')} ) ] ) (command.WhileUntil keyword: <KW_While while> cond: [(C {(read)} {(len)} {(rest)})] body: (command.DoGroup children: [ (command.If arms: [ (if_arm cond: [ (C {(test)} {(DQ ($ VSub_DollarName '$len'))} {(Lit_Other '=')} { (word_part.CommandSubPart command_list: (command.CommandList children: [ (command.Pipeline children: [ (C {(echo)} { (DQ ($ VSub_DollarName '$len') (' ') ($ VSub_DollarName '$rest') ) } ) (C {(wc)} {(-c)}) ] negated: F ) ] ) left_token: <Left_CommandSub '$('> ) } ) ] action: [ (command.Case to_match: {(DQ ($ VSub_DollarName '$rest'))} arms: [ (case_arm pat_list: [{($ VSub_DollarName '$header') (Lit_Other '*')}] action: [ (C {(echo)} { (DQ (word_part.BracedVarSub token: <VSub_Name rest> suffix_op: (suffix_op.StringUnary op_id: VOp1_Pound arg_word: {($ VSub_DollarName '$header')} ) ) ) } ) ] ) ] ) ] ) ] ) ] ) redirects: [ (redir.Redir op: <Redir_Less '<'> fd: 16777215 arg_word: {(DQ ($ VSub_DollarName '$file'))} ) ] ) ] ) ) (command.FuncDef name: check_tar body: (command.BraceGroup children: [ (command.Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (lhs_expr.LhsName name:tarfile) op: Equal rhs: {($ VSub_Number '$1') (.tar)} ) ] ) (command.Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (lhs_expr.LhsName name:listfile) op: Equal rhs: {($ VSub_Number '$1') (.lst)} ) ] ) (command.Assignment keyword: Assign_None pairs: [(assign_pair lhs:(lhs_expr.LhsName name:dir) op:Equal rhs:{($ VSub_Number '$1')})] ) (command.Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (lhs_expr.LhsName name:dir_with_prefix) op: Equal rhs: {($ VSub_DollarName '$dir') (/) ($ VSub_Number '$2')} ) ] ) (C {(test_expect_success)} {(SQ <' extract tar archive'>)} {(SQ <'\n'> <'\t\t(mkdir $dir && cd $dir && "$TAR" xf -) <$tarfile\n'> <'\t'>)} ) (C {(test_expect_success)} {(TAR_NEEDS_PAX_FALLBACK)} {(SQ <' interpret pax headers'>)} { (SQ <'\n'> <'\t\t(\n'> <'\t\t\tcd $dir &&\n'> <'\t\t\tfor header in *.paxheader\n'> <'\t\t\tdo\n'> <'\t\t\t\tdata=${header%.paxheader}.data &&\n'> <'\t\t\t\tif test -h $data || test -e $data\n'> <'\t\t\t\tthen\n'> <'\t\t\t\t\tpath=$(get_pax_header $header path) &&\n'> <'\t\t\t\t\tif test -n "$path"\n'> <'\t\t\t\t\tthen\n'> <'\t\t\t\t\t\tmv "$data" "$path"\n'> <'\t\t\t\t\tfi\n'> <'\t\t\t\tfi\n'> <'\t\t\tdone\n'> <'\t\t)\n'> <'\t'> ) } ) (C {(test_expect_success)} {(SQ <' validate filenames'>)} { (SQ <'\n'> <'\t\t(cd ${dir_with_prefix}a && find .) | sort >$listfile &&\n'> <'\t\ttest_cmp a.lst $listfile\n'> <'\t'> ) } ) (C {(test_expect_success)} {(SQ <' validate file contents'>)} {(SQ <'\n'> <'\t\tdiff -r a ${dir_with_prefix}a\n'> <'\t'>)} ) ] ) ) (C {(test_expect_success)} {(SQ <'populate workdir'>)} { (SQ <'mkdir a &&\n'> <' echo simple textfile >a/a &&\n'> <' ten=0123456789 && hundred=$ten$ten$ten$ten$ten$ten$ten$ten$ten$ten &&\n'> <' echo long filename >a/four$hundred &&\n'> <' mkdir a/bin &&\n'> <' test-genrandom "frotz" 500000 >a/bin/sh &&\n'> <' printf "A\\$Format:%s\\$O" "$SUBSTFORMAT" >a/substfile1 &&\n'> <' printf "A not substituted O" >a/substfile2 &&\n'> <' if test_have_prereq SYMLINKS; then\n'> <'\tln -s a a/l1\n'> <' else\n'> <'\tprintf %s a > a/l1\n'> <' fi &&\n'> <' (p=long_path_to_a_file && cd a &&\n'> <' for depth in 1 2 3 4 5; do mkdir $p && cd $p; done &&\n'> <' echo text >file_with_long_path) &&\n'> <' (cd a && find .) | sort >a.lst'> ) } ) (C {(test_expect_success)} {(SQ <'add ignored file'>)} { (SQ <'echo ignore me >a/ignored &&\n'> <' echo ignored export-ignore >.git/info/attributes'> ) } ) (C {(test_expect_success)} {(SQ <'add files to repository'>)} { (SQ <'\n'> <'\tgit add a &&\n'> <'\tGIT_COMMITTER_DATE="2005-05-27 22:00" git commit -m initial\n'> ) } ) (C {(test_expect_success)} {(SQ <'setup export-subst'>)} { (SQ <'\n'> <'\techo "substfile?" export-subst >>.git/info/attributes &&\n'> <'\tgit log --max-count=1 "--pretty=format:A${SUBSTFORMAT}O" HEAD \\\n'> <'\t\t>a/substfile1\n'> ) } ) (C {(test_expect_success)} {(SQ <'create bare clone'>)} { (SQ <'git clone --bare . bare.git &&\n'> <' cp .git/info/attributes bare.git/info/attributes'> ) } ) (C {(test_expect_success)} {(SQ <'remove ignored file'>)} {(SQ <'rm a/ignored'>)}) (C {(test_expect_success)} {(SQ <'git archive'>)} {(SQ <'git archive HEAD >b.tar'>)}) (C {(check_tar)} {(b)}) (C {(test_expect_success)} {(SQ <'git archive --prefix=prefix/'>)} {(SQ <'\n'> <'\tgit archive --prefix=prefix/ HEAD >with_prefix.tar\n'>)} ) (C {(check_tar)} {(with_prefix)} {(prefix/)}) (C {(test_expect_success)} {(SQ <'git-archive --prefix=olde-'>)} {(SQ <'\n'> <'\tgit archive --prefix=olde- HEAD >with_olde-prefix.tar\n'>)} ) (C {(check_tar)} {(with_olde-prefix)} {(olde-)}) (C {(test_expect_success)} {(SQ <'git archive on large files'>)} { (SQ <'\n'> <' test_config core.bigfilethreshold 1 &&\n'> <' git archive HEAD >b3.tar &&\n'> <' test_cmp_bin b.tar b3.tar\n'> ) } ) (C {(test_expect_success)} {(SQ <'git archive in a bare repo'>)} {(SQ <'(cd bare.git && git archive HEAD) >b3.tar'>)} ) (C {(test_expect_success)} {(SQ <'git archive vs. the same in a bare repo'>)} {(SQ <'test_cmp_bin b.tar b3.tar'>)} ) (C {(test_expect_success)} {(SQ <'git archive with --output'>)} {(SQ <'git archive --output=b4.tar HEAD &&\n'> <' test_cmp_bin b.tar b4.tar'>)} ) (C {(test_expect_success)} {(SQ <'git archive --remote'>)} {(SQ <'git archive --remote=. HEAD >b5.tar &&\n'> <' test_cmp_bin b.tar b5.tar'>)} ) (C {(test_expect_success)} {(SQ <'validate file modification time'>)} { (SQ <'mkdir extract &&\n'> <' "$TAR" xf b.tar -C extract a/a &&\n'> <' test-chmtime -v +0 extract/a/a |cut -f 1 >b.mtime &&\n'> <' echo "1117231200" >expected.mtime &&\n'> <' test_cmp expected.mtime b.mtime'> ) } ) (C {(test_expect_success)} {(SQ <'git get-tar-commit-id'>)} { (SQ <'git get-tar-commit-id <b.tar >b.commitid &&\n'> <' test_cmp .git/$(git symbolic-ref HEAD) b.commitid'> ) } ) (C {(test_expect_success)} {(SQ <'git archive with --output, override inferred format'>)} { (SQ <'\n'> <'\tgit archive --format=tar --output=d4.zip HEAD &&\n'> <'\ttest_cmp_bin b.tar d4.zip\n'> ) } ) (C {(test_expect_success)} {(SQ <'git archive --list outside of a git repo'>)} {(SQ <'GIT_DIR=some/non-existing/directory git archive --list'>)} ) (C {(test_expect_success)} {(SQ <'clients cannot access unreachable commits'>)} { (SQ <'\n'> <'\ttest_commit unreachable &&\n'> <'\tsha1=$(git rev-parse HEAD) &&\n'> <'\tgit reset --hard HEAD^ &&\n'> <'\tgit archive $sha1 >remote.tar &&\n'> <'\ttest_must_fail git archive --remote=. $sha1 >remote.tar\n'> ) } ) (C {(test_expect_success)} {(SQ <'upload-archive can allow unreachable commits'>)} { (SQ <'\n'> <'\ttest_commit unreachable1 &&\n'> <'\tsha1=$(git rev-parse HEAD) &&\n'> <'\tgit reset --hard HEAD^ &&\n'> <'\tgit archive $sha1 >remote.tar &&\n'> <'\ttest_config uploadarchive.allowUnreachable true &&\n'> <'\tgit archive --remote=. $sha1 >remote.tar\n'> ) } ) (C {(test_expect_success)} {(SQ <'setup tar filters'>)} { (SQ <'\n'> <'\tgit config tar.tar.foo.command "tr ab ba" &&\n'> <'\tgit config tar.bar.command "tr ab ba" &&\n'> <'\tgit config tar.bar.remote true &&\n'> <'\tgit config tar.invalid baz\n'> ) } ) (C {(test_expect_success)} {(SQ <'archive --list mentions user filter'>)} { (SQ <'\n'> <'\tgit archive --list >output &&\n'> <'\tgrep "^tar\\.foo\\$" output &&\n'> <'\tgrep "^bar\\$" output\n'> ) } ) (C {(test_expect_success)} {(SQ <'archive --list shows only enabled remote filters'>)} { (SQ <'\n'> <'\tgit archive --list --remote=. >output &&\n'> <'\t! grep "^tar\\.foo\\$" output &&\n'> <'\tgrep "^bar\\$" output\n'> ) } ) (C {(test_expect_success)} {(SQ <'invoke tar filter by format'>)} { (SQ <'\n'> <'\tgit archive --format=tar.foo HEAD >config.tar.foo &&\n'> <'\ttr ab ba <config.tar.foo >config.tar &&\n'> <'\ttest_cmp_bin b.tar config.tar &&\n'> <'\tgit archive --format=bar HEAD >config.bar &&\n'> <'\ttr ab ba <config.bar >config.tar &&\n'> <'\ttest_cmp_bin b.tar config.tar\n'> ) } ) (C {(test_expect_success)} {(SQ <'invoke tar filter by extension'>)} { (SQ <'\n'> <'\tgit archive -o config-implicit.tar.foo HEAD &&\n'> <'\ttest_cmp_bin config.tar.foo config-implicit.tar.foo &&\n'> <'\tgit archive -o config-implicit.bar HEAD &&\n'> <'\ttest_cmp_bin config.tar.foo config-implicit.bar\n'> ) } ) (C {(test_expect_success)} {(SQ <'default output format remains tar'>)} { (SQ <'\n'> <'\tgit archive -o config-implicit.baz HEAD &&\n'> <'\ttest_cmp_bin b.tar config-implicit.baz\n'> ) } ) (C {(test_expect_success)} {(SQ <'extension matching requires dot'>)} { (SQ <'\n'> <'\tgit archive -o config-implicittar.foo HEAD &&\n'> <'\ttest_cmp_bin b.tar config-implicittar.foo\n'> ) } ) (C {(test_expect_success)} {(SQ <'only enabled filters are available remotely'>)} { (SQ <'\n'> <'\ttest_must_fail git archive --remote=. --format=tar.foo HEAD \\\n'> <'\t\t>remote.tar.foo &&\n'> <'\tgit archive --remote=. --format=bar >remote.bar HEAD &&\n'> <'\ttest_cmp_bin remote.bar config.bar\n'> ) } ) (C {(test_expect_success)} {(GZIP)} {(SQ <'git archive --format=tgz'>)} {(SQ <'\n'> <'\tgit archive --format=tgz HEAD >j.tgz\n'>)} ) (C {(test_expect_success)} {(GZIP)} {(SQ <'git archive --format=tar.gz'>)} { (SQ <'\n'> <'\tgit archive --format=tar.gz HEAD >j1.tar.gz &&\n'> <'\ttest_cmp_bin j.tgz j1.tar.gz\n'> ) } ) (C {(test_expect_success)} {(GZIP)} {(SQ <'infer tgz from .tgz filename'>)} {(SQ <'\n'> <'\tgit archive --output=j2.tgz HEAD &&\n'> <'\ttest_cmp_bin j.tgz j2.tgz\n'>)} ) (C {(test_expect_success)} {(GZIP)} {(SQ <'infer tgz from .tar.gz filename'>)} { (SQ <'\n'> <'\tgit archive --output=j3.tar.gz HEAD &&\n'> <'\ttest_cmp_bin j.tgz j3.tar.gz\n'>) } ) (C {(test_expect_success)} {(GZIP)} {(SQ <'extract tgz file'>)} {(SQ <'\n'> <'\tgzip -d -c <j.tgz >j.tar &&\n'> <'\ttest_cmp_bin b.tar j.tar\n'>)} ) (C {(test_expect_success)} {(GZIP)} {(SQ <'remote tar.gz is allowed by default'>)} { (SQ <'\n'> <'\tgit archive --remote=. --format=tar.gz HEAD >remote.tar.gz &&\n'> <'\ttest_cmp_bin j.tgz remote.tar.gz\n'> ) } ) (C {(test_expect_success)} {(GZIP)} {(SQ <'remote tar.gz can be disabled'>)} { (SQ <'\n'> <'\tgit config tar.tar.gz.remote false &&\n'> <'\ttest_must_fail git archive --remote=. --format=tar.gz HEAD \\\n'> <'\t\t>remote.tar.gz\n'> ) } ) (C {(test_expect_success)} {(SQ <'archive and :(glob)'>)} { (SQ <'\n'> <'\tgit archive -v HEAD -- ":(glob)**/sh" >/dev/null 2>actual &&\n'> <'\tcat >expect <<EOF &&\n'> <'a/\n'> <'a/bin/\n'> <'a/bin/sh\n'> <'EOF\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'catch non-matching pathspec'>)} {(SQ <'\n'> <'\ttest_must_fail git archive -v HEAD -- "*.abc" >/dev/null\n'>)} ) (command.FuncDef name: tar_info body: (command.BraceGroup children: [ (command.Pipeline children: [ (C {(DQ ($ VSub_DollarName '$TAR'))} {(tvf)} {(DQ ($ VSub_Number '$1'))}) (C {(awk)} {(SQ <'{\n'> <'\t\tsplit($4, date, "-")\n'> <'\t\tprint $3 " " date[1]\n'> <'\t}'>)} ) ] negated: F ) ] ) ) (C {(test_lazy_prereq)} {(TAR_HUGE)} { (SQ <'\n'> <'\techo "68719476737 4147" >expect &&\n'> <'\ttar_info "$TEST_DIRECTORY"/t5000/huge-and-future.tar >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(LONG_IS_64BIT)} {(SQ <'set up repository with huge blob'>)} { (SQ <'\n'> <'\tobj_d=19 &&\n'> <'\tobj_f=f9c8273ec45a8938e6999cb59b3ff66739902a &&\n'> <'\tobj=${obj_d}${obj_f} &&\n'> <'\tmkdir -p .git/objects/$obj_d &&\n'> <'\tcp "$TEST_DIRECTORY"/t5000/$obj .git/objects/$obj_d/$obj_f &&\n'> <'\trm -f .git/index &&\n'> <'\tgit update-index --add --cacheinfo 100644,$obj,huge &&\n'> <'\tgit commit -m huge\n'> ) } ) (C {(test_expect_success)} {(LONG_IS_64BIT)} {(SQ <'generate tar with huge size'>)} { (SQ <'\n'> <'\t{\n'> <'\t\tgit archive HEAD\n'> <'\t\techo $? >exit-code\n'> <'\t} | test_copy_bytes 4096 >huge.tar &&\n'> <'\techo 141 >expect &&\n'> <'\ttest_cmp expect exit-code\n'> ) } ) (C {(test_expect_success)} {(TAR_HUGE) (Lit_Comma ',') (LONG_IS_64BIT)} {(SQ <'system tar can read our huge size'>)} { (SQ <'\n'> <'\techo 68719476737 >expect &&\n'> <'\ttar_info huge.tar | cut -d" " -f1 >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(LONG_IS_64BIT)} {(SQ <'set up repository with far-future commit'>)} { (SQ <'\n'> <'\trm -f .git/index &&\n'> <'\techo content >file &&\n'> <'\tgit add file &&\n'> <'\tGIT_COMMITTER_DATE="@68719476737 +0000" \\\n'> <'\t\tgit commit -m "tempori parendum"\n'> ) } ) (C {(test_expect_success)} {(LONG_IS_64BIT)} {(SQ <'generate tar with future mtime'>)} {(SQ <'\n'> <'\tgit archive HEAD >future.tar\n'>)} ) (C {(test_expect_success)} {(TAR_HUGE) (Lit_Comma ',') (LONG_IS_64BIT)} {(SQ <'system tar can read our future mtime'>)} { (SQ <'\n'> <'\techo 4147 >expect &&\n'> <'\ttar_info future.tar | cut -d" " -f2 >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_done)}) ] )