(CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (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"> ) } spids: [13] ) ] spids: [13] ) (C {(.)} {(./test-lib.sh)}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SUBSTFORMAT) op: Equal rhs: {(Lit_Other "%") (H) (Lit_Other "%") (n)} spids: [42] ) ] spids: [42] ) (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">)}) (FuncDef name: get_pax_header body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:file) op: Equal rhs: {($ VSub_Number "$1")} spids: [80] ) ] spids: [80] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:header) op: Equal rhs: {($ VSub_Number "$2") (Lit_Other "=")} spids: [84] ) ] spids: [84] ) (While cond: [(C {(read)} {(len)} {(rest)})] body: (DoGroup children: [ (If arms: [ (if_arm cond: [ (C {(test)} {(DQ ($ VSub_Name "$len"))} {(Lit_Other "=")} { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {(DQ ($ VSub_Name "$len") (" ") ($ VSub_Name "$rest"))} ) (C {(wc)} {(-c)}) ] negated: False ) ] ) left_token: <Left_CommandSub "$("> spids: [112 126] ) } ) ] action: [ (Case to_match: {(DQ ($ VSub_Name "$rest"))} arms: [ (case_arm pat_list: [{($ VSub_Name "$header") (Lit_Other "*")}] action: [ (C {(echo)} { (DQ (BracedVarSub token: <VSub_Name rest> suffix_op: (StringUnary op_id: VOp1_Pound arg_word: {($ VSub_Name "$header")} ) spids: [149 153] ) ) } ) ] spids: [141 143 157 -1] ) ] spids: [132 138 160] ) ] spids: [-1 129] ) ] spids: [-1 163] ) ] spids: [99 166] ) redirects: [ (Redir op_id: Redir_Less fd: -1 arg_word: {(DQ ($ VSub_Name "$file"))} spids: [168] ) ] ) ] spids: [77] ) spids: [73 76] ) (FuncDef name: check_tar body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:tarfile) op: Equal rhs: {($ VSub_Number "$1") (.tar)} spids: [183] ) ] spids: [183] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:listfile) op: Equal rhs: {($ VSub_Number "$1") (.lst)} spids: [188] ) ] spids: [188] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:dir) op: Equal rhs: {($ VSub_Number "$1")} spids: [193] ) ] spids: [193] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:dir_with_prefix) op: Equal rhs: {($ VSub_Name "$dir") (/) ($ VSub_Number "$2")} spids: [197] ) ] spids: [197] ) (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">)} ) ] spids: [180] ) spids: [176 179] ) (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">)} ) (FuncDef name: tar_info body: (BraceGroup children: [ (Pipeline children: [ (C {(DQ ($ VSub_Name "$TAR"))} {(tvf)} {(DQ ($ VSub_Number "$1"))}) (C {(awk)} { (SQ <"{\n"> <"\t\tsplit($4, date, \"-\")\n"> <"\t\tprint $3 \" \" date[1]\n"> <"\t}"> ) } ) ] negated: False ) ] spids: [892] ) spids: [887 891] ) (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)}) ] )