(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: {(SQ (Token id:Id.Lit_Chars val:'external diff interface test' span_id:6))}
          spids: [4]
        )
      ]
    )
    (C {(.)} {(./test-lib.sh)})
    (C {(test_expect_success)} {(setup)} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:20) (Token id:Id.Lit_Chars val:'\n' span_id:21) 
          (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:22) (Token id:Id.Lit_Chars val:'\techo initial >file &&\n' span_id:23) 
          (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:24) (Token id:Id.Lit_Chars val:'\tgit commit -m initial &&\n' span_id:25) 
          (Token id:Id.Lit_Chars val:'\n' span_id:26) (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:27) 
          (Token id:Id.Lit_Chars val:'\techo second >file &&\n' span_id:28) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:29) 
          (Token id:Id.Lit_Chars val:'\tgit commit -m second &&\n' span_id:30) (Token id:Id.Lit_Chars val:'\n' span_id:31) (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:32) 
          (Token id:Id.Lit_Chars val:'\techo third >file\n' span_id:33)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'GIT_EXTERNAL_DIFF environment' span_id:40))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:44) (Token id:Id.Lit_Chars val:'\n' span_id:45) 
          (Token id:Id.Lit_Chars val:'\tGIT_EXTERNAL_DIFF=echo git diff | {\n' span_id:46) 
          (Token
            id: Id.Lit_Chars
            val: '\t\tread path oldfile oldhex oldmode newfile newhex newmode &&\n'
            span_id: 47
          ) (Token id:Id.Lit_Chars val:'\t\ttest "z$path" = zfile &&\n' span_id:48) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$oldmode" = z100644 &&\n' span_id:49) (Token id:Id.Lit_Chars val:'\t\ttest "z$newhex" = "z$_z40" &&\n' span_id:50) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$newmode" = z100644 &&\n' span_id:51) (Token id:Id.Lit_Chars val:'\t\toh=$(git rev-parse --verify HEAD:file) &&\n' span_id:52) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$oh" = "z$oldhex"\n' span_id:53) (Token id:Id.Lit_Chars val:'\t}\n' span_id:54) (Token id:Id.Lit_Chars val:'\n' span_id:55)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'GIT_EXTERNAL_DIFF environment should apply only to diff'
            span_id: 62
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:66) (Token id:Id.Lit_Chars val:'\n' span_id:67) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_EXTERNAL_DIFF=echo git log -p -1 HEAD |\n'
            span_id: 68
          ) (Token id:Id.Lit_Chars val:'\tgrep "^diff --git a/file b/file"\n' span_id:69) 
          (Token id:Id.Lit_Chars val:'\n' span_id:70)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'GIT_EXTERNAL_DIFF environment and --no-ext-diff' span_id:77))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:81) (Token id:Id.Lit_Chars val:'\n' span_id:82) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_EXTERNAL_DIFF=echo git diff --no-ext-diff |\n'
            span_id: 83
          ) (Token id:Id.Lit_Chars val:'\tgrep "^diff --git a/file b/file"\n' span_id:84) 
          (Token id:Id.Lit_Chars val:'\n' span_id:85)
        )
      }
    )
    (C {(test_expect_success)} {(SYMLINKS)} 
      {(SQ (Token id:Id.Lit_Chars val:'typechange diff' span_id:94))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:98) 
          (Token id:Id.Lit_Chars val:'\trm -f file &&\n' span_id:99) (Token id:Id.Lit_Chars val:'\tln -s elif file &&\n' span_id:100) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_EXTERNAL_DIFF=echo git diff  | {\n'
            span_id: 101
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\t\tread path oldfile oldhex oldmode newfile newhex newmode &&\n'
            span_id: 102
          ) (Token id:Id.Lit_Chars val:'\t\ttest "z$path" = zfile &&\n' span_id:103) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$oldmode" = z100644 &&\n' span_id:104) (Token id:Id.Lit_Chars val:'\t\ttest "z$newhex" = "z$_z40" &&\n' span_id:105) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$newmode" = z120000 &&\n' span_id:106) (Token id:Id.Lit_Chars val:'\t\toh=$(git rev-parse --verify HEAD:file) &&\n' span_id:107) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$oh" = "z$oldhex"\n' span_id:108) (Token id:Id.Lit_Chars val:'\t} &&\n' span_id:109) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_EXTERNAL_DIFF=echo git diff --no-ext-diff >actual &&\n'
            span_id: 110
          ) (Token id:Id.Lit_Chars val:'\tgit diff >expect &&\n' span_id:111) 
          (Token id:Id.Lit_Chars val:'\ttest_cmp expect actual\n' span_id:112)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:diff.external span_id:119))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:123) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:124) (Token id:Id.Lit_Chars val:'\techo third >file &&\n' span_id:125) 
          (Token id:Id.Lit_Chars val:'\ttest_config diff.external echo &&\n' span_id:126) (Token id:Id.Lit_Chars val:'\tgit diff | {\n' span_id:127) 
          (Token
            id: Id.Lit_Chars
            val: '\t\tread path oldfile oldhex oldmode newfile newhex newmode &&\n'
            span_id: 128
          ) (Token id:Id.Lit_Chars val:'\t\ttest "z$path" = zfile &&\n' span_id:129) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$oldmode" = z100644 &&\n' span_id:130) (Token id:Id.Lit_Chars val:'\t\ttest "z$newhex" = "z$_z40" &&\n' span_id:131) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$newmode" = z100644 &&\n' span_id:132) (Token id:Id.Lit_Chars val:'\t\toh=$(git rev-parse --verify HEAD:file) &&\n' span_id:133) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$oh" = "z$oldhex"\n' span_id:134) (Token id:Id.Lit_Chars val:'\t}\n' span_id:135)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'diff.external should apply only to diff' span_id:142))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:146) 
          (Token id:Id.Lit_Chars val:'\ttest_config diff.external echo &&\n' span_id:147) (Token id:Id.Lit_Chars val:'\tgit log -p -1 HEAD |\n' span_id:148) 
          (Token id:Id.Lit_Chars val:'\tgrep "^diff --git a/file b/file"\n' span_id:149)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'diff.external and --no-ext-diff' span_id:156))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:160) 
          (Token id:Id.Lit_Chars val:'\ttest_config diff.external echo &&\n' span_id:161) (Token id:Id.Lit_Chars val:'\tgit diff --no-ext-diff |\n' span_id:162) 
          (Token id:Id.Lit_Chars val:'\tgrep "^diff --git a/file b/file"\n' span_id:163)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'diff attribute' span_id:170))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:174) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:175) (Token id:Id.Lit_Chars val:'\techo third >file &&\n' span_id:176) 
          (Token id:Id.Lit_Chars val:'\n' span_id:177) (Token id:Id.Lit_Chars val:'\tgit config diff.parrot.command echo &&\n' span_id:178) 
          (Token id:Id.Lit_Chars val:'\n' span_id:179) (Token id:Id.Lit_Chars val:'\techo >.gitattributes "file diff=parrot" &&\n' span_id:180) 
          (Token id:Id.Lit_Chars val:'\n' span_id:181) (Token id:Id.Lit_Chars val:'\tgit diff | {\n' span_id:182) 
          (Token
            id: Id.Lit_Chars
            val: '\t\tread path oldfile oldhex oldmode newfile newhex newmode &&\n'
            span_id: 183
          ) (Token id:Id.Lit_Chars val:'\t\ttest "z$path" = zfile &&\n' span_id:184) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$oldmode" = z100644 &&\n' span_id:185) (Token id:Id.Lit_Chars val:'\t\ttest "z$newhex" = "z$_z40" &&\n' span_id:186) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$newmode" = z100644 &&\n' span_id:187) (Token id:Id.Lit_Chars val:'\t\toh=$(git rev-parse --verify HEAD:file) &&\n' span_id:188) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$oh" = "z$oldhex"\n' span_id:189) (Token id:Id.Lit_Chars val:'\t}\n' span_id:190) (Token id:Id.Lit_Chars val:'\n' span_id:191)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'diff attribute should apply only to diff' span_id:198))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:202) (Token id:Id.Lit_Chars val:'\n' span_id:203) 
          (Token id:Id.Lit_Chars val:'\tgit log -p -1 HEAD |\n' span_id:204) (Token id:Id.Lit_Chars val:'\tgrep "^diff --git a/file b/file"\n' span_id:205) 
          (Token id:Id.Lit_Chars val:'\n' span_id:206)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'diff attribute and --no-ext-diff' span_id:213))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:217) (Token id:Id.Lit_Chars val:'\n' span_id:218) 
          (Token id:Id.Lit_Chars val:'\tgit diff --no-ext-diff |\n' span_id:219) (Token id:Id.Lit_Chars val:'\tgrep "^diff --git a/file b/file"\n' span_id:220) 
          (Token id:Id.Lit_Chars val:'\n' span_id:221)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'diff attribute' span_id:228))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:232) (Token id:Id.Lit_Chars val:'\n' span_id:233) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit config --unset diff.parrot.command &&\n'
            span_id: 234
          ) (Token id:Id.Lit_Chars val:'\tgit config diff.color.command echo &&\n' span_id:235) 
          (Token id:Id.Lit_Chars val:'\n' span_id:236) (Token id:Id.Lit_Chars val:'\techo >.gitattributes "file diff=color" &&\n' span_id:237) 
          (Token id:Id.Lit_Chars val:'\n' span_id:238) (Token id:Id.Lit_Chars val:'\tgit diff | {\n' span_id:239) 
          (Token
            id: Id.Lit_Chars
            val: '\t\tread path oldfile oldhex oldmode newfile newhex newmode &&\n'
            span_id: 240
          ) (Token id:Id.Lit_Chars val:'\t\ttest "z$path" = zfile &&\n' span_id:241) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$oldmode" = z100644 &&\n' span_id:242) (Token id:Id.Lit_Chars val:'\t\ttest "z$newhex" = "z$_z40" &&\n' span_id:243) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$newmode" = z100644 &&\n' span_id:244) (Token id:Id.Lit_Chars val:'\t\toh=$(git rev-parse --verify HEAD:file) &&\n' span_id:245) 
          (Token id:Id.Lit_Chars val:'\t\ttest "z$oh" = "z$oldhex"\n' span_id:246) (Token id:Id.Lit_Chars val:'\t}\n' span_id:247) (Token id:Id.Lit_Chars val:'\n' span_id:248)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'diff attribute should apply only to diff' span_id:255))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:259) (Token id:Id.Lit_Chars val:'\n' span_id:260) 
          (Token id:Id.Lit_Chars val:'\tgit log -p -1 HEAD |\n' span_id:261) (Token id:Id.Lit_Chars val:'\tgrep "^diff --git a/file b/file"\n' span_id:262) 
          (Token id:Id.Lit_Chars val:'\n' span_id:263)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'diff attribute and --no-ext-diff' span_id:270))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:274) (Token id:Id.Lit_Chars val:'\n' span_id:275) 
          (Token id:Id.Lit_Chars val:'\tgit diff --no-ext-diff |\n' span_id:276) (Token id:Id.Lit_Chars val:'\tgrep "^diff --git a/file b/file"\n' span_id:277) 
          (Token id:Id.Lit_Chars val:'\n' span_id:278)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'GIT_EXTERNAL_DIFF trumps diff.external' span_id:285))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:289) 
          (Token id:Id.Lit_Chars val:'\t>.gitattributes &&\n' span_id:290) (Token id:Id.Lit_Chars val:'\ttest_config diff.external "echo ext-global" &&\n' span_id:291) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_EXTERNAL_DIFF="echo ext-env" git diff | grep ext-env\n'
            span_id: 292
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'attributes trump GIT_EXTERNAL_DIFF and diff.external'
            span_id: 299
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:303) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_config diff.foo.command "echo ext-attribute" &&\n'
            span_id: 304
          ) (Token id:Id.Lit_Chars val:'\ttest_config diff.external "echo ext-global" &&\n' span_id:305) 
          (Token
            id: Id.Lit_Chars
            val: '\techo "file diff=foo" >.gitattributes &&\n'
            span_id: 306
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_EXTERNAL_DIFF="echo ext-env" git diff | grep ext-attribute\n'
            span_id: 307
          )
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'no diff with -diff' span_id:314))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:318) 
          (Token
            id: Id.Lit_Chars
            val: '\techo >.gitattributes "file -diff" &&\n'
            span_id: 319
          ) (Token id:Id.Lit_Chars val:'\tgit diff | grep Binary\n' span_id:320)
        )
      }
    )
    (command.Pipeline
      children: [
        (C {(echo)} {(NULZbetweenZwords)})
        (command.Simple
          words: [{(perl)} {(-pe)} {(SQ (Token id:Id.Lit_Chars val:'y/Z/\\000/' span_id:335))}]
          redirects: [
            (redir.Redir
              op: (Token id:Id.Redir_Great val:'>' span_id:338)
              fd: -1
              arg_word: {(file)}
            )
          ]
        )
      ]
      negated: F
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'force diff with "diff"' span_id:346))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:350) 
          (Token id:Id.Lit_Chars val:'\techo >.gitattributes "file diff" &&\n' span_id:351) (Token id:Id.Lit_Chars val:'\tgit diff >actual &&\n' span_id:352) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_cmp "$TEST_DIRECTORY"/t4020/diff.NUL actual\n'
            span_id: 353
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'GIT_EXTERNAL_DIFF with more than one changed files'
            span_id: 360
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:364) 
          (Token id:Id.Lit_Chars val:'\techo anotherfile > file2 &&\n' span_id:365) (Token id:Id.Lit_Chars val:'\tgit add file2 &&\n' span_id:366) 
          (Token id:Id.Lit_Chars val:'\tgit commit -m "added 2nd file" &&\n' span_id:367) (Token id:Id.Lit_Chars val:'\techo modified >file2 &&\n' span_id:368) 
          (Token id:Id.Lit_Chars val:'\tGIT_EXTERNAL_DIFF=echo git diff\n' span_id:369)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'GIT_EXTERNAL_DIFF path counter/total' span_id:376))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:380) 
          (Token
            id: Id.Lit_Chars
            val: '\twrite_script external-diff.sh <<-\\EOF &&\n'
            span_id: 381
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\techo $GIT_DIFF_PATH_COUNTER of $GIT_DIFF_PATH_TOTAL >>counter.txt\n'
            span_id: 382
          ) (Token id:Id.Lit_Chars val:'\tEOF\n' span_id:383) 
          (Token id:Id.Lit_Chars val:'\t>counter.txt &&\n' span_id:384) (Token id:Id.Lit_Chars val:'\tcat >expect <<-\\EOF &&\n' span_id:385) 
          (Token id:Id.Lit_Chars val:'\t1 of 2\n' span_id:386) (Token id:Id.Lit_Chars val:'\t2 of 2\n' span_id:387) (Token id:Id.Lit_Chars val:'\tEOF\n' span_id:388) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_EXTERNAL_DIFF=./external-diff.sh git diff &&\n'
            span_id: 389
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp expect counter.txt\n' span_id:390)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'GIT_EXTERNAL_DIFF generates pretty paths' span_id:397))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:401) 
          (Token id:Id.Lit_Chars val:'\ttouch file.ext &&\n' span_id:402) (Token id:Id.Lit_Chars val:'\tgit add file.ext &&\n' span_id:403) 
          (Token id:Id.Lit_Chars val:'\techo with extension > file.ext &&\n' span_id:404) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_EXTERNAL_DIFF=echo git diff file.ext | grep ......_file\\.ext &&\n'
            span_id: 405
          ) (Token id:Id.Lit_Chars val:'\tgit update-index --force-remove file.ext &&\n' span_id:406) 
          (Token id:Id.Lit_Chars val:'\trm file.ext\n' span_id:407)
        )
      }
    )
    (command.Simple
      words: [{(echo)} {(DQ ('#!') ($ Id.VSub_DollarName '$SHELL_PATH'))}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:418)
          fd: -1
          arg_word: {(fake-diff.sh)}
        )
      ]
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_DGreat val:'>>' span_id:423)
          fd: -1
          arg_word: {(fake-diff.sh)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:427)
          fd: -1
          here_begin: 
            {(word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\E' span_id:428)) 
              (OF)
            }
          here_end_span_id: 432
          stdin_parts: [('cat $2 >> crlfed.txt\n')]
        )
      ]
    )
    (C {(chmod)} {(a) (Id.Lit_Other '+') (x)} {(fake-diff.sh)})
    (command.ShFunction
      name: keep_only_cr
      body: 
        (command.BraceGroup
          children: [(C {(tr)} {(-dc)} {(SQ (Token id:Id.Lit_Chars val:'\\015' span_id:455))})]
        )
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'external diff with autocrlf = true' span_id:464))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:468) 
          (Token id:Id.Lit_Chars val:'\ttest_config core.autocrlf true &&\n' span_id:469) (Token id:Id.Lit_Chars val:'\tGIT_EXTERNAL_DIFF=./fake-diff.sh git diff &&\n' span_id:470) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest $(wc -l < crlfed.txt) = $(cat crlfed.txt | keep_only_cr | wc -c)\n'
            span_id: 471
          )
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'diff --cached' span_id:478))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:482) 
          (Token id:Id.Lit_Chars val:'\ttest_config core.autocrlf true &&\n' span_id:483) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:484) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit update-index --assume-unchanged file &&\n'
            span_id: 485
          ) (Token id:Id.Lit_Chars val:'\techo second >file &&\n' span_id:486) 
          (Token id:Id.Lit_Chars val:'\tgit diff --cached >actual &&\n' span_id:487) (Token id:Id.Lit_Chars val:'\ttest_cmp "$TEST_DIRECTORY"/t4020/diff.NUL actual\n' span_id:488)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'clean up crlf leftovers' span_id:495))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:499) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit update-index --no-assume-unchanged file &&\n'
            span_id: 500
          ) (Token id:Id.Lit_Chars val:'\trm -f file* &&\n' span_id:501) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard\n' span_id:502)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'submodule diff' span_id:509))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:513) 
          (Token id:Id.Lit_Chars val:'\tgit init sub &&\n' span_id:514) (Token id:Id.Lit_Chars val:'\t( cd sub && test_commit sub1 ) &&\n' span_id:515) 
          (Token id:Id.Lit_Chars val:'\tgit add sub &&\n' span_id:516) (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:517) 
          (Token id:Id.Lit_Chars val:'\tgit commit -m "add submodule" &&\n' span_id:518) (Token id:Id.Lit_Chars val:'\t( cd sub && test_commit sub2 ) &&\n' span_id:519) 
          (Token
            id: Id.Lit_Chars
            val: '\twrite_script gather_pre_post.sh <<-\\EOF &&\n'
            span_id: 520
          ) (Token id:Id.Lit_Chars val:'\techo "$1 $4" # path, mode\n' span_id:521) 
          (Token id:Id.Lit_Chars val:'\tcat "$2" # old file\n' span_id:522) (Token id:Id.Lit_Chars val:'\tcat "$5" # new file\n' span_id:523) 
          (Token id:Id.Lit_Chars val:'\tEOF\n' span_id:524) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_EXTERNAL_DIFF=./gather_pre_post.sh git diff >actual &&\n'
            span_id: 525
          ) (Token id:Id.Lit_Chars val:'\tcat >expected <<-EOF &&\n' span_id:526) 
          (Token id:Id.Lit_Chars val:'\tsub 160000\n' span_id:527) (Token id:Id.Lit_Chars val:'\tSubproject commit $(git rev-parse HEAD:sub)\n' span_id:528) 
          (Token
            id: Id.Lit_Chars
            val: '\tSubproject commit $(cd sub && git rev-parse HEAD)\n'
            span_id: 529
          ) (Token id:Id.Lit_Chars val:'\tEOF\n' span_id:530) 
          (Token id:Id.Lit_Chars val:'\ttest_cmp expected actual\n' span_id:531)
        )
      }
    )
    (C {(test_done)})
  ]
)