(CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <'blob conversion via gitattributes'>)} spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (SimpleCommand words: [{(cat)}] redirects: [ (HereDoc op_id: Redir_DLess fd: 16777215 body: { (DQ ('#!') ($ VSub_Name '$SHELL_PATH') ('\n') ('tr ') (" 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ") (" 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM'\n") ) } do_expansion: True here_end: EOF was_filled: True spids: [17] ) (Redir op_id:Redir_Great fd:16777215 arg_word:{(rot13.sh)} spids:[20]) ] ) (C {(chmod)} {(Lit_Other '+') (x)} {(rot13.sh)}) (C {(test_expect_success)} {(setup)} { (SQ <'\n'> <'\tgit config filter.rot13.smudge ./rot13.sh &&\n'> <'\tgit config filter.rot13.clean ./rot13.sh &&\n'> <'\n'> <'\t{\n'> <'\t echo "*.t filter=rot13"\n'> <'\t echo "*.i ident"\n'> <'\t} >.gitattributes &&\n'> <'\n'> <'\t{\n'> <'\t echo a b c d e f g h i j k l m\n'> <'\t echo n o p q r s t u v w x y z\n'> <'\t echo '> ) (EscapedLiteralPart token:<Lit_EscapedChar "\\'">) (SQ <'$Id$'>) (EscapedLiteralPart token:<Lit_EscapedChar "\\'">) (SQ <'\n'> <'\t} >test &&\n'> <'\tcat test >test.t &&\n'> <'\tcat test >test.o &&\n'> <'\tcat test >test.i &&\n'> <'\tgit add test test.t test.i &&\n'> <'\trm -f test test.t test.i &&\n'> <'\tgit checkout -- test test.t test.i\n'> ) } ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:script) op: Equal rhs: {(SQ <'s/^\\$Id: \\([0-9a-f]*\\) \\$/\\1/p'>)} spids: [76] ) ] spids: [76] ) (C {(test_expect_success)} {(check)} { (SQ <'\n'> <'\n'> <'\tcmp test.o test &&\n'> <'\tcmp test.o test.t &&\n'> <'\n'> <'\t# ident should be stripped in the repository\n'> <'\tgit diff --raw --exit-code :test :test.i &&\n'> <'\tid=$(git rev-parse --verify :test) &&\n'> <'\tembedded=$(sed -ne "$script" test.i) &&\n'> <'\ttest "z$id" = "z$embedded" &&\n'> <'\n'> <'\tgit cat-file blob :test.t > test.r &&\n'> <'\n'> <'\t./rot13.sh < test.o > test.t &&\n'> <'\tcmp test.r test.t\n'> ) } ) (C {(test_expect_success)} {(expanded_in_repo)} { (SQ <'\n'> <'\t{\n'> <'\t\techo "File with expanded keywords"\n'> <'\t\techo "\\$Id\\$"\n'> <'\t\techo "\\$Id:\\$"\n'> <'\t\techo "\\$Id: 0000000000000000000000000000000000000000 \\$"\n'> <'\t\techo "\\$Id: NoSpaceAtEnd\\$"\n'> <'\t\techo "\\$Id:NoSpaceAtFront \\$"\n'> <'\t\techo "\\$Id:NoSpaceAtEitherEnd\\$"\n'> <'\t\techo "\\$Id: NoTerminatingSymbol"\n'> <'\t\techo "\\$Id: Foreign Commit With Spaces \\$"\n'> <'\t} >expanded-keywords.0 &&\n'> <'\n'> <'\t{\n'> <'\t\tcat expanded-keywords.0 &&\n'> <'\t\tprintf "\\$Id: NoTerminatingSymbolAtEOF"\n'> <'\t} >expanded-keywords &&\n'> <'\tcat expanded-keywords >expanded-keywords-crlf &&\n'> <'\tgit add expanded-keywords expanded-keywords-crlf &&\n'> <'\tgit commit -m "File with keywords expanded" &&\n'> <'\tid=$(git rev-parse --verify :expanded-keywords) &&\n'> <'\n'> <'\t{\n'> <'\t\techo "File with expanded keywords"\n'> <'\t\techo "\\$Id: $id \\$"\n'> <'\t\techo "\\$Id: $id \\$"\n'> <'\t\techo "\\$Id: $id \\$"\n'> <'\t\techo "\\$Id: $id \\$"\n'> <'\t\techo "\\$Id: $id \\$"\n'> <'\t\techo "\\$Id: $id \\$"\n'> <'\t\techo "\\$Id: NoTerminatingSymbol"\n'> <'\t\techo "\\$Id: Foreign Commit With Spaces \\$"\n'> <'\t} >expected-output.0 &&\n'> <'\t{\n'> <'\t\tcat expected-output.0 &&\n'> <'\t\tprintf "\\$Id: NoTerminatingSymbolAtEOF"\n'> <'\t} >expected-output &&\n'> <'\t{\n'> <'\t\tappend_cr <expected-output.0 &&\n'> <'\t\tprintf "\\$Id: NoTerminatingSymbolAtEOF"\n'> <'\t} >expected-output-crlf &&\n'> <'\t{\n'> <'\t\techo "expanded-keywords ident"\n'> <'\t\techo "expanded-keywords-crlf ident text eol=crlf"\n'> <'\t} >>.gitattributes &&\n'> <'\n'> <'\trm -f expanded-keywords expanded-keywords-crlf &&\n'> <'\n'> <'\tgit checkout -- expanded-keywords &&\n'> <'\ttest_cmp expanded-keywords expected-output &&\n'> <'\n'> <'\tgit checkout -- expanded-keywords-crlf &&\n'> <'\ttest_cmp expanded-keywords-crlf expected-output-crlf\n'> ) } ) (C {(test_expect_success)} {(SQ <'filter shell-escaped filenames'>)} { (SQ <'\n'> <'\tcat >argc.sh <<-EOF &&\n'> <'\t#!$SHELL_PATH\n'> <'\tcat >/dev/null\n'> <'\techo argc: \\$# "\\$@"\n'> <'\tEOF\n'> <'\tnormal=name-no-magic &&\n'> <'\tspecial="name with '> ) (EscapedLiteralPart token:<Lit_EscapedChar "\\'">) (SQ <sq>) (EscapedLiteralPart token:<Lit_EscapedChar "\\'">) (SQ <' and \\$x" &&\n'> <'\techo some test text >"$normal" &&\n'> <'\techo some test text >"$special" &&\n'> <'\tgit add "$normal" "$special" &&\n'> <'\tgit commit -q -m "add files" &&\n'> <'\techo "name* filter=argc" >.gitattributes &&\n'> <'\n'> <'\t# delete the files and check them out again, using a smudge filter\n'> <'\t# that will count the args and echo the command-line back to us\n'> <'\tgit config filter.argc.smudge "sh ./argc.sh %f" &&\n'> <'\trm "$normal" "$special" &&\n'> <'\tgit checkout -- "$normal" "$special" &&\n'> <'\n'> <'\t# make sure argc.sh counted the right number of args\n'> <'\techo "argc: 1 $normal" >expect &&\n'> <'\ttest_cmp expect "$normal" &&\n'> <'\techo "argc: 1 $special" >expect &&\n'> <'\ttest_cmp expect "$special" &&\n'> <'\n'> <'\t# do the same thing, but with more args in the filter expression\n'> <'\tgit config filter.argc.smudge "sh ./argc.sh %f --my-extra-arg" &&\n'> <'\trm "$normal" "$special" &&\n'> <'\tgit checkout -- "$normal" "$special" &&\n'> <'\n'> <'\t# make sure argc.sh counted the right number of args\n'> <'\techo "argc: 2 $normal --my-extra-arg" >expect &&\n'> <'\ttest_cmp expect "$normal" &&\n'> <'\techo "argc: 2 $special --my-extra-arg" >expect &&\n'> <'\ttest_cmp expect "$special" &&\n'> <'\t:\n'> ) } ) (C {(test_expect_success)} {(SQ <'required filter should filter data'>)} { (SQ <'\n'> <'\tgit config filter.required.smudge ./rot13.sh &&\n'> <'\tgit config filter.required.clean ./rot13.sh &&\n'> <'\tgit config filter.required.required true &&\n'> <'\n'> <'\techo "*.r filter=required" >.gitattributes &&\n'> <'\n'> <'\tcat test.o >test.r &&\n'> <'\tgit add test.r &&\n'> <'\n'> <'\trm -f test.r &&\n'> <'\tgit checkout -- test.r &&\n'> <'\tcmp test.o test.r &&\n'> <'\n'> <'\t./rot13.sh <test.o >expected &&\n'> <'\tgit cat-file blob :test.r >actual &&\n'> <'\tcmp expected actual\n'> ) } ) (C {(test_expect_success)} {(SQ <'required filter smudge failure'>)} { (SQ <'\n'> <'\tgit config filter.failsmudge.smudge false &&\n'> <'\tgit config filter.failsmudge.clean cat &&\n'> <'\tgit config filter.failsmudge.required true &&\n'> <'\n'> <'\techo "*.fs filter=failsmudge" >.gitattributes &&\n'> <'\n'> <'\techo test >test.fs &&\n'> <'\tgit add test.fs &&\n'> <'\trm -f test.fs &&\n'> <'\ttest_must_fail git checkout -- test.fs\n'> ) } ) (C {(test_expect_success)} {(SQ <'required filter clean failure'>)} { (SQ <'\n'> <'\tgit config filter.failclean.smudge cat &&\n'> <'\tgit config filter.failclean.clean false &&\n'> <'\tgit config filter.failclean.required true &&\n'> <'\n'> <'\techo "*.fc filter=failclean" >.gitattributes &&\n'> <'\n'> <'\techo test >test.fc &&\n'> <'\ttest_must_fail git add test.fc\n'> ) } ) (C {(test_expect_success)} {(SQ <'filtering large input to small output should use little memory'>)} { (SQ <'\n'> <'\tgit config filter.devnull.clean "cat >/dev/null" &&\n'> <'\tgit config filter.devnull.required true &&\n'> <'\tfor i in $(test_seq 1 30); do printf "%1048576d" 1; done >30MB &&\n'> <'\techo "30MB filter=devnull" >.gitattributes &&\n'> <'\tGIT_MMAP_LIMIT=1m GIT_ALLOC_LIMIT=1m git add 30MB\n'> ) } ) (C {(test_expect_success)} {(SQ <'filter that does not read is fine'>)} { (SQ <'\n'> <'\ttest-genrandom foo $((128 * 1024 + 1)) >big &&\n'> <'\techo "big filter=epipe" >.gitattributes &&\n'> <'\tgit config filter.epipe.clean "echo xyzzy" &&\n'> <'\tgit add big &&\n'> <'\tgit cat-file blob :big >actual &&\n'> <'\techo xyzzy >expect &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {(test_expect_success)} {(EXPENSIVE)} {(SQ <'filter large file'>)} { (SQ <'\n'> <'\tgit config filter.largefile.smudge cat &&\n'> <'\tgit config filter.largefile.clean cat &&\n'> <'\tfor i in $(test_seq 1 2048); do printf "%1048576d" 1; done >2GB &&\n'> <'\techo "2GB filter=largefile" >.gitattributes &&\n'> <'\tgit add 2GB 2>err &&\n'> <'\t! test -s err &&\n'> <'\trm -f 2GB &&\n'> <'\tgit checkout -- 2GB 2>err &&\n'> <'\t! test -s err\n'> ) } ) (C {(test_expect_success)} {(DQ ('filter: clean empty file'))} { (SQ <'\n'> <'\tgit config filter.in-repo-header.clean "echo cleaned && cat" &&\n'> <'\tgit config filter.in-repo-header.smudge "sed 1d" &&\n'> <'\n'> <'\techo "empty-in-worktree filter=in-repo-header" >>.gitattributes &&\n'> <'\t>empty-in-worktree &&\n'> <'\n'> <'\techo cleaned >expected &&\n'> <'\tgit add empty-in-worktree &&\n'> <'\tgit show :empty-in-worktree >actual &&\n'> <'\ttest_cmp expected actual\n'> ) } ) (C {(test_expect_success)} {(DQ ('filter: smudge empty file'))} { (SQ <'\n'> <'\tgit config filter.empty-in-repo.clean "cat >/dev/null" &&\n'> <'\tgit config filter.empty-in-repo.smudge "echo smudged && cat" &&\n'> <'\n'> <'\techo "empty-in-repo filter=empty-in-repo" >>.gitattributes &&\n'> <'\techo dead data walking >empty-in-repo &&\n'> <'\tgit add empty-in-repo &&\n'> <'\n'> <'\techo smudged >expected &&\n'> <'\tgit checkout-index --prefix=filtered- empty-in-repo &&\n'> <'\ttest_cmp expected filtered-empty-in-repo\n'> ) } ) (C {(test_expect_success)} {(SQ <'disable filter with empty override'>)} { (SQ <'\n'> <'\ttest_config_global filter.disable.smudge false &&\n'> <'\ttest_config_global filter.disable.clean false &&\n'> <'\ttest_config filter.disable.smudge false &&\n'> <'\ttest_config filter.disable.clean false &&\n'> <'\n'> <'\techo "*.disable filter=disable" >.gitattributes &&\n'> <'\n'> <'\techo test >test.disable &&\n'> <'\tgit -c filter.disable.clean= add test.disable 2>err &&\n'> <'\ttest_must_be_empty err &&\n'> <'\trm -f test.disable &&\n'> <'\tgit -c filter.disable.smudge= checkout -- test.disable 2>err &&\n'> <'\ttest_must_be_empty err\n'> ) } ) (C {(test_expect_success)} {(SQ <'diff does not reuse worktree files that need cleaning'>)} { (SQ <'\n'> <'\ttest_config filter.counter.clean "echo . >>count; sed s/^/clean:/" &&\n'> <'\techo "file filter=counter" >.gitattributes &&\n'> <'\ttest_commit one file &&\n'> <'\ttest_commit two file &&\n'> <'\n'> <'\t>count &&\n'> <'\tgit diff-tree -p HEAD &&\n'> <'\ttest_line_count = 0 count\n'> ) } ) (C {(test_done)}) ] )