(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: {(SQ <'CRLF conversion'>)}
          spids: [4]
        )
      ]
    )
    (C {<.>} {<'./test-lib.sh'>})
    (command.ShFunction
      name: has_cr
      body: 
        (BraceGroup
          children: [
            (command.Pipeline
              children: [
                (command.Simple
                  words: [{<tr>} {(SQ <'\\015'>)} {<Q>}]
                  redirects: [
                    (redir
                      op: <Id.Redir_Less '<'>
                      loc: (redir_loc.Fd fd:0)
                      arg: {(DQ ($ Id.VSub_Number '$1'))}
                    )
                  ]
                  do_fork: T
                )
                (command.Simple
                  words: [{<grep>} {<Q>}]
                  redirects: [
                    (redir
                      op: <Id.Redir_Great '>'>
                      loc: (redir_loc.Fd fd:1)
                      arg: {<'/dev/null'>}
                    )
                  ]
                  do_fork: T
                )
              ]
              negated: F
            )
          ]
        )
    )
    (command.ShFunction
      name: munge_cr
      body: 
        (BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp]
              children: [
                (command.Simple
                  words: [{(DQ (${ Id.VSub_Number 1) <_cr>)}]
                  redirects: [
                    (redir
                      op: <Id.Redir_Less '<'>
                      loc: (redir_loc.Fd fd:0)
                      arg: {(DQ ($ Id.VSub_Number '$2'))}
                    )
                    (redir
                      op: <Id.Redir_Great '>'>
                      loc: (redir_loc.Fd fd:1)
                      arg: {<tmp>}
                    )
                  ]
                  do_fork: T
                )
                (C {<mv>} {<tmp>} {(DQ ($ Id.VSub_Number '$2'))})
              ]
            )
          ]
        )
    )
    (C {<test_expect_success>} {<setup>} 
      {
        (SQ <'\n'> <'\n'> <'\tgit config core.autocrlf false &&\n'> <'\n'> 
          <'\tfor w in Hello world how are you; do echo $w; done >one &&\n'> <'\tmkdir dir &&\n'> <'\tfor w in I am very very fine thank you; do echo $w; done >dir/two &&\n'> 
          <'\tfor w in Oh here is NULQin text here; do echo $w; done | q_to_nul >three &&\n'> <'\tgit add . &&\n'> <'\n'> <'\tgit commit -m initial &&\n'> <'\n'> 
          <'\tone=$(git rev-parse HEAD:one) &&\n'> <'\tdir=$(git rev-parse HEAD:dir) &&\n'> <'\ttwo=$(git rev-parse HEAD:dir/two) &&\n'> 
          <'\tthree=$(git rev-parse HEAD:three) &&\n'> <'\n'> <'\tfor w in Some extra lines here; do echo $w; done >>one &&\n'> 
          <'\tgit diff >patch.file &&\n'> <'\tpatched=$(git hash-object --stdin <one) &&\n'> <'\tgit read-tree --reset -u HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'safecrlf: autocrlf=input, all CRLF'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tgit config core.autocrlf input &&\n'> 
          <'\tgit config core.safecrlf true &&\n'> <'\n'> <'\tfor w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&\n'> 
          <'\ttest_must_fail git add allcrlf\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'safecrlf: autocrlf=input, mixed LF/CRLF'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tgit config core.autocrlf input &&\n'> 
          <'\tgit config core.safecrlf true &&\n'> <'\n'> <'\tfor w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&\n'> 
          <'\ttest_must_fail git add mixed\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'safecrlf: autocrlf=true, all LF'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tgit config core.autocrlf true &&\n'> 
          <'\tgit config core.safecrlf true &&\n'> <'\n'> <'\tfor w in I am all LF; do echo $w; done >alllf &&\n'> <'\ttest_must_fail git add alllf\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'safecrlf: autocrlf=true mixed LF/CRLF'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tgit config core.autocrlf true &&\n'> 
          <'\tgit config core.safecrlf true &&\n'> <'\n'> <'\tfor w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&\n'> 
          <'\ttest_must_fail git add mixed\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'safecrlf: print warning only once'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tgit config core.autocrlf input &&\n'> 
          <'\tgit config core.safecrlf warn &&\n'> <'\n'> <'\tfor w in I am all LF; do echo $w; done >doublewarn &&\n'> <'\tgit add doublewarn &&\n'> 
          <'\tgit commit -m "nowarn" &&\n'> <'\tfor w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >doublewarn &&\n'> 
          <'\tgit add doublewarn 2>err &&\n'> <'\tif test_have_prereq C_LOCALE_OUTPUT\n'> <'\tthen\n'> 
          <'\t\ttest $(grep "CRLF will be replaced by LF" err | wc -l) = 1\n'> <'\tfi\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'safecrlf: git diff demotes safecrlf=true to warn'>)} 
      {
        (SQ <'\n'> <'\tgit config core.autocrlf input &&\n'> <'\tgit config core.safecrlf true &&\n'> 
          <'\tgit diff HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'switch off autocrlf, safecrlf, reset HEAD'>)} 
      {
        (SQ <'\n'> <'\tgit config core.autocrlf false &&\n'> <'\tgit config core.safecrlf false &&\n'> 
          <'\tgit reset --hard HEAD^\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'update with autocrlf=input'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\tgit read-tree --reset -u HEAD &&\n'> <'\tgit config core.autocrlf input &&\n'> <'\tmunge_cr append one &&\n'> 
          <'\tmunge_cr append dir/two &&\n'> <'\tgit update-index -- one dir/two &&\n'> <'\tdiffers=$(git diff-index --cached HEAD) &&\n'> 
          <'\tverbose test -z "$differs"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'update with autocrlf=true'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\tgit read-tree --reset -u HEAD &&\n'> <'\tgit config core.autocrlf true &&\n'> <'\tmunge_cr append one &&\n'> 
          <'\tmunge_cr append dir/two &&\n'> <'\tgit update-index -- one dir/two &&\n'> <'\tdiffers=$(git diff-index --cached HEAD) &&\n'> 
          <'\tverbose test -z "$differs"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'checkout with autocrlf=true'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\tgit config core.autocrlf true &&\n'> <'\tgit read-tree --reset -u HEAD &&\n'> <'\tmunge_cr remove one &&\n'> 
          <'\tmunge_cr remove dir/two &&\n'> <'\tgit update-index -- one dir/two &&\n'> <'\ttest "$one" = $(git hash-object --stdin <one) &&\n'> 
          <'\ttest "$two" = $(git hash-object --stdin <dir/two) &&\n'> <'\tdiffers=$(git diff-index --cached HEAD) &&\n'> <'\tverbose test -z "$differs"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'checkout with autocrlf=input'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\tgit config core.autocrlf input &&\n'> <'\tgit read-tree --reset -u HEAD &&\n'> <'\ttest_must_fail has_cr one &&\n'> 
          <'\ttest_must_fail has_cr two &&\n'> <'\tgit update-index -- one dir/two &&\n'> <'\ttest "$one" = $(git hash-object --stdin <one) &&\n'> 
          <'\ttest "$two" = $(git hash-object --stdin <dir/two) &&\n'> <'\tdiffers=$(git diff-index --cached HEAD) &&\n'> <'\tverbose test -z "$differs"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'apply patch (autocrlf=input)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\tgit config core.autocrlf input &&\n'> <'\tgit read-tree --reset -u HEAD &&\n'> <'\n'> <'\tgit apply patch.file &&\n'> 
          <'\tverbose test "$patched" = "$(git hash-object --stdin <one)"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'apply patch --cached (autocrlf=input)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\tgit config core.autocrlf input &&\n'> <'\tgit read-tree --reset -u HEAD &&\n'> <'\n'> <'\tgit apply --cached patch.file &&\n'> 
          <'\tverbose test "$patched" = $(git rev-parse :one)\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'apply patch --index (autocrlf=input)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\tgit config core.autocrlf input &&\n'> <'\tgit read-tree --reset -u HEAD &&\n'> <'\n'> <'\tgit apply --index patch.file &&\n'> 
          <'\tverbose test "$patched" = $(git rev-parse :one) &&\n'> <'\tverbose test "$patched" = $(git hash-object --stdin <one)\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'apply patch (autocrlf=true)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\tgit config core.autocrlf true &&\n'> <'\tgit read-tree --reset -u HEAD &&\n'> <'\n'> <'\tgit apply patch.file &&\n'> 
          <'\tverbose test "$patched" = "$(remove_cr <one | git hash-object --stdin)"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'apply patch --cached (autocrlf=true)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\tgit config core.autocrlf true &&\n'> <'\tgit read-tree --reset -u HEAD &&\n'> <'\n'> <'\tgit apply --cached patch.file &&\n'> 
          <'\tverbose test "$patched" = $(git rev-parse :one)\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'apply patch --index (autocrlf=true)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\tgit config core.autocrlf true &&\n'> <'\tgit read-tree --reset -u HEAD &&\n'> <'\n'> <'\tgit apply --index patch.file &&\n'> 
          <'\tverbose test "$patched" = $(git rev-parse :one) &&\n'> <'\tverbose test "$patched" = "$(remove_cr <one | git hash-object --stdin)"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'.gitattributes says two is binary'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\techo "two -crlf" >.gitattributes &&\n'> <'\tgit config core.autocrlf true &&\n'> <'\tgit read-tree --reset -u HEAD &&\n'> <'\n'> 
          <'\ttest_must_fail has_cr dir/two &&\n'> <'\tverbose has_cr one &&\n'> <'\ttest_must_fail has_cr three\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'.gitattributes says two is input'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\techo "two crlf=input" >.gitattributes &&\n'> <'\tgit read-tree --reset -u HEAD &&\n'> <'\n'> <'\ttest_must_fail has_cr dir/two\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'.gitattributes says two and three are text'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -f tmp one dir/two three &&\n'> 
          <'\techo "t* crlf" >.gitattributes &&\n'> <'\tgit read-tree --reset -u HEAD &&\n'> <'\n'> <'\tverbose has_cr dir/two &&\n'> 
          <'\tverbose has_cr three\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'in-tree .gitattributes (1)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "one -crlf" >>.gitattributes &&\n'> <'\tgit add .gitattributes &&\n'> 
          <'\tgit commit -m "Add .gitattributes" &&\n'> <'\n'> <'\trm -rf tmp one dir .gitattributes patch.file three &&\n'> 
          <'\tgit read-tree --reset -u HEAD &&\n'> <'\n'> <'\ttest_must_fail has_cr one &&\n'> <'\tverbose has_cr three\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'in-tree .gitattributes (2)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -rf tmp one dir .gitattributes patch.file three &&\n'> 
          <'\tgit read-tree --reset HEAD &&\n'> <'\tgit checkout-index -f -q -u -a &&\n'> <'\n'> <'\ttest_must_fail has_cr one &&\n'> 
          <'\tverbose has_cr three\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'in-tree .gitattributes (3)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -rf tmp one dir .gitattributes patch.file three &&\n'> 
          <'\tgit read-tree --reset HEAD &&\n'> <'\tgit checkout-index -u .gitattributes &&\n'> <'\tgit checkout-index -u one dir/two three &&\n'> 
          <'\n'> <'\ttest_must_fail has_cr one &&\n'> <'\tverbose has_cr three\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'in-tree .gitattributes (4)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\trm -rf tmp one dir .gitattributes patch.file three &&\n'> 
          <'\tgit read-tree --reset HEAD &&\n'> <'\tgit checkout-index -u one dir/two three &&\n'> <'\tgit checkout-index -u .gitattributes &&\n'> 
          <'\n'> <'\ttest_must_fail has_cr one &&\n'> <'\tverbose has_cr three\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'checkout with existing .gitattributes'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tgit config core.autocrlf true &&\n'> 
          <'\tgit config --unset core.safecrlf &&\n'> <'\techo ".file2 -crlfQ" | q_to_cr >> .gitattributes &&\n'> <'\tgit add .gitattributes &&\n'> 
          <'\tgit commit -m initial &&\n'> <'\techo ".file -crlfQ" | q_to_cr >> .gitattributes &&\n'> <'\techo "contents" > .file &&\n'> 
          <'\tgit add .gitattributes .file &&\n'> <'\tgit commit -m second &&\n'> <'\n'> <'\tgit checkout master~1 &&\n'> <'\tgit checkout master &&\n'> 
          <'\ttest "$(git diff-files --raw)" = ""\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'checkout when deleting .gitattributes'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tgit rm .gitattributes &&\n'> 
          <'\techo "contentsQ" | q_to_cr > .file2 &&\n'> <'\tgit add .file2 &&\n'> <'\tgit commit -m third &&\n'> <'\n'> <'\tgit checkout master~1 &&\n'> 
          <'\tgit checkout master &&\n'> <'\thas_cr .file2\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'invalid .gitattributes (must not crash)'>)} 
      {(SQ <'\n'> <'\n'> <'\techo "three +crlf" >>.gitattributes &&\n'> <'\tgit diff\n'> <'\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'setting up for new autocrlf tests'>)} 
      {
        (SQ <'\n'> <'\tgit config core.autocrlf false &&\n'> <'\tgit config core.safecrlf false &&\n'> 
          <'\trm -rf .????* * &&\n'> <'\tfor w in I am all LF; do echo $w; done >alllf &&\n'> 
          <'\tfor w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed &&\n'> <'\tfor w in I am all CRLF; do echo $w; done | append_cr >allcrlf &&\n'> <'\tgit add -A . &&\n'> 
          <'\tgit commit -m "alllf, allcrlf and mixed only" &&\n'> <'\tgit tag -a -m "message" autocrlf-checkpoint\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'report no change after setting autocrlf'>)} 
      {
        (SQ <'\n'> <'\tgit config core.autocrlf true &&\n'> <'\ttouch * &&\n'> 
          <'\tgit diff --exit-code\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'files are clean after checkout'>)} 
      {(SQ <'\n'> <'\trm * &&\n'> <'\tgit checkout -f &&\n'> <'\tgit diff --exit-code\n'>)}
    )
    (command.ShFunction
      name: cr_to_Q_no_NL
      body: 
        (BraceGroup
          children: [
            (command.Pipeline
              children: [(C {<tr>} {(SQ <'\\015'>)} {<Q>}) (C {<tr>} {<-d>} {(SQ <'\\012'>)})]
              negated: F
            )
          ]
        )
    )
    (C {<test_expect_success>} {(SQ <'LF only file gets CRLF with autocrlf'>)} 
      {(SQ <'\n'> <'\ttest "$(cr_to_Q_no_NL < alllf)" = "IQamQallQLFQ"\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'Mixed file is still mixed with autocrlf'>)} 
      {(SQ <'\n'> <'\ttest "$(cr_to_Q_no_NL < mixed)" = "OhhereisCRLFQintext"\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'CRLF only file has CRLF with autocrlf'>)} 
      {(SQ <'\n'> <'\ttest "$(cr_to_Q_no_NL < allcrlf)" = "IQamQallQCRLFQ"\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'New CRLF file gets LF in repo'>)} 
      {
        (SQ <'\n'> <'\ttr -d "\\015" < alllf | append_cr > alllf2 &&\n'> <'\tgit add alllf2 &&\n'> 
          <'\tgit commit -m "alllf2 added" &&\n'> <'\tgit config core.autocrlf false &&\n'> <'\trm * &&\n'> <'\tgit checkout -f &&\n'> 
          <'\ttest_cmp alllf alllf2\n'>
        )
      }
    )
    (C {<test_done>})
  ]
)