(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:'git filter-branch' span_id:6))}
          spids: [4]
        )
      ]
    )
    (C {(.)} {(./test-lib.sh)})
    (C {(.)} {(DQ ($ Id.VSub_DollarName '$TEST_DIRECTORY') (/lib-gpg.sh))})
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:setup span_id:24))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:28) 
          (Token id:Id.Lit_Chars val:'\ttest_commit A &&\n' span_id:29) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_COMMITTER_DATE="@0 +0000" GIT_AUTHOR_DATE="@0 +0000" &&\n'
            span_id: 30
          ) (Token id:Id.Lit_Chars val:'\ttest_commit --notick B &&\n' span_id:31) 
          (Token id:Id.Lit_Chars val:'\tgit checkout -b branch B &&\n' span_id:32) (Token id:Id.Lit_Chars val:'\ttest_commit D &&\n' span_id:33) 
          (Token id:Id.Lit_Chars val:'\tmkdir dir &&\n' span_id:34) (Token id:Id.Lit_Chars val:'\ttest_commit dir/D &&\n' span_id:35) 
          (Token id:Id.Lit_Chars val:'\ttest_commit E &&\n' span_id:36) (Token id:Id.Lit_Chars val:'\tgit checkout master &&\n' span_id:37) 
          (Token id:Id.Lit_Chars val:'\ttest_commit C &&\n' span_id:38) (Token id:Id.Lit_Chars val:'\tgit checkout branch &&\n' span_id:39) 
          (Token id:Id.Lit_Chars val:'\tgit merge C &&\n' span_id:40) (Token id:Id.Lit_Chars val:'\tgit tag F &&\n' span_id:41) 
          (Token id:Id.Lit_Chars val:'\ttest_commit G &&\n' span_id:42) (Token id:Id.Lit_Chars val:'\ttest_commit H\n' span_id:43)
        )
      }
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:H)
          op: assign_op.Equal
          rhs: 
            {
              (command_sub
                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:82)
                command_list: (command.CommandList children:[(C {(git)} {(rev-parse)} {(H)})])
              )
            }
          spids: [81]
        )
      ]
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'rewrite identically' span_id:94))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:98) 
          (Token id:Id.Lit_Chars val:'\tgit filter-branch branch\n' span_id:99)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'result is really identical' span_id:105))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:109) 
          (Token id:Id.Lit_Chars val:'\ttest $H = $(git rev-parse HEAD)\n' span_id:110)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'rewrite bare repository identically' span_id:117))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:121) 
          (Token
            id: Id.Lit_Chars
            val: '\t(git config core.bare true && cd .git &&\n'
            span_id: 122
          ) (Token id:Id.Lit_Chars val:'\t git filter-branch branch > filter-output 2>&1 &&\n' span_id:123) 
          (Token id:Id.Lit_Chars val:'\t! fgrep fatal filter-output)\n' span_id:124)
        )
      }
    )
    (C {(git)} {(config)} {(core.bare)} {(false)})
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'result is really identical' span_id:138))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:142) 
          (Token id:Id.Lit_Chars val:'\ttest $H = $(git rev-parse HEAD)\n' span_id:143)
        )
      }
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:TRASHDIR)
          op: assign_op.Equal
          rhs: 
            {
              (command_sub
                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:148)
                command_list: (command.CommandList children:[(C {(pwd)})])
              )
            }
          spids: [147]
        )
      ]
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'correct GIT_DIR while using -d' span_id:155))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:159) 
          (Token id:Id.Lit_Chars val:'\tmkdir drepo &&\n' span_id:160) (Token id:Id.Lit_Chars val:'\t( cd drepo &&\n' span_id:161) 
          (Token id:Id.Lit_Chars val:'\tgit init &&\n' span_id:162) (Token id:Id.Lit_Chars val:'\ttest_commit drepo &&\n' span_id:163) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch -d "$TRASHDIR/dfoo" \\\n'
            span_id: 164
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\t\t--index-filter "cp \\"$TRASHDIR\\"/dfoo/backup-refs \\"$TRASHDIR\\"" \\\n'
            span_id: 165
          ) (Token id:Id.Lit_Chars val:'\t) &&\n' span_id:166) 
          (Token id:Id.Lit_Chars val:'\tgrep drepo "$TRASHDIR/backup-refs"\n' span_id:167)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'tree-filter works with -d' span_id:174))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:178) 
          (Token id:Id.Lit_Chars val:'\tgit init drepo-tree &&\n' span_id:179) (Token id:Id.Lit_Chars val:'\t(\n' span_id:180) 
          (Token id:Id.Lit_Chars val:'\t\tcd drepo-tree &&\n' span_id:181) (Token id:Id.Lit_Chars val:'\t\ttest_commit one &&\n' span_id:182) 
          (Token
            id: Id.Lit_Chars
            val: '\t\tgit filter-branch -d "$TRASHDIR/dfoo" \\\n'
            span_id: 183
          ) (Token id:Id.Lit_Chars val:'\t\t\t--tree-filter "echo changed >one.t" &&\n' span_id:184) 
          (Token id:Id.Lit_Chars val:'\t\techo changed >expect &&\n' span_id:185) (Token id:Id.Lit_Chars val:'\t\tgit cat-file blob HEAD:one.t >actual &&\n' span_id:186) 
          (Token id:Id.Lit_Chars val:'\t\ttest_cmp expect actual &&\n' span_id:187) (Token id:Id.Lit_Chars val:'\t\ttest_cmp one.t actual\n' span_id:188) 
          (Token id:Id.Lit_Chars val:'\t)\n' span_id:189)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'Fail if commit filter fails' span_id:196))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:200) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git filter-branch -f --commit-filter "exit 1" HEAD\n'
            span_id: 201
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'rewrite, renaming a specific file' span_id:208))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:212) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch -f --tree-filter "mv D.t doh || :" HEAD\n'
            span_id: 213
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'test that the file was renamed' span_id:220))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:224) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest D = "$(git show HEAD:doh --)" &&\n'
            span_id: 225
          ) (Token id:Id.Lit_Chars val:'\t! test -f D.t &&\n' span_id:226) 
          (Token id:Id.Lit_Chars val:'\ttest -f doh &&\n' span_id:227) (Token id:Id.Lit_Chars val:'\ttest D = "$(cat doh)"\n' span_id:228)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'rewrite, renaming a specific directory' span_id:235))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:239) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch -f --tree-filter "mv dir diroh || :" HEAD\n'
            span_id: 240
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'test that the directory was renamed' span_id:247))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:251) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest dir/D = "$(git show HEAD:diroh/D.t --)" &&\n'
            span_id: 252
          ) (Token id:Id.Lit_Chars val:'\t! test -d dir &&\n' span_id:253) 
          (Token id:Id.Lit_Chars val:'\ttest -d diroh &&\n' span_id:254) (Token id:Id.Lit_Chars val:'\t! test -d diroh/dir &&\n' span_id:255) 
          (Token id:Id.Lit_Chars val:'\ttest -f diroh/D.t &&\n' span_id:256) (Token id:Id.Lit_Chars val:'\ttest dir/D = "$(cat diroh/D.t)"\n' span_id:257)
        )
      }
    )
    (C {(git)} {(tag)} {(oldD)} {(HEAD) (Id.Lit_TildeLike '~4')})
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'rewrite one branch, keeping a side branch' span_id:273))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:277) 
          (Token id:Id.Lit_Chars val:'\tgit branch modD oldD &&\n' span_id:278) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch -f --tree-filter "mv B.t boh || :" D..modD\n'
            span_id: 279
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'common ancestor is still common (unchanged)' span_id:286))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:290) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest "$(git merge-base modD D)" = "$(git rev-parse B)"\n'
            span_id: 291
          )
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'filter subdirectory only' span_id:298))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:302) 
          (Token id:Id.Lit_Chars val:'\tmkdir subdir &&\n' span_id:303) (Token id:Id.Lit_Chars val:'\ttouch subdir/new &&\n' span_id:304) 
          (Token id:Id.Lit_Chars val:'\tgit add subdir/new &&\n' span_id:305) (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:306) 
          (Token id:Id.Lit_Chars val:'\tgit commit -m "subdir" &&\n' span_id:307) (Token id:Id.Lit_Chars val:'\techo H > A.t &&\n' span_id:308) 
          (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:309) (Token id:Id.Lit_Chars val:'\tgit commit -m "not subdir" A.t &&\n' span_id:310) 
          (Token id:Id.Lit_Chars val:'\techo A > subdir/new &&\n' span_id:311) (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:312) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit commit -m "again subdir" subdir/new &&\n'
            span_id: 313
          ) (Token id:Id.Lit_Chars val:'\tgit rm A.t &&\n' span_id:314) 
          (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:315) (Token id:Id.Lit_Chars val:'\tgit commit -m "again not subdir" &&\n' span_id:316) 
          (Token id:Id.Lit_Chars val:'\tgit branch sub &&\n' span_id:317) (Token id:Id.Lit_Chars val:'\tgit branch sub-earlier HEAD~2 &&\n' span_id:318) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch -f --subdirectory-filter subdir \\\n'
            span_id: 319
          ) (Token id:Id.Lit_Chars val:'\t\trefs/heads/sub refs/heads/sub-earlier\n' span_id:320)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'subdirectory filter result looks okay' span_id:327))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:331) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest 2 = $(git rev-list sub | wc -l) &&\n'
            span_id: 332
          ) (Token id:Id.Lit_Chars val:'\tgit show sub:new &&\n' span_id:333) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git show sub:subdir &&\n'
            span_id: 334
          ) (Token id:Id.Lit_Chars val:'\tgit show sub-earlier:new &&\n' span_id:335) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git show sub-earlier:subdir\n'
            span_id: 336
          )
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'more setup' span_id:343))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:347) 
          (Token id:Id.Lit_Chars val:'\tgit checkout master &&\n' span_id:348) (Token id:Id.Lit_Chars val:'\tmkdir subdir &&\n' span_id:349) 
          (Token id:Id.Lit_Chars val:'\techo A > subdir/new &&\n' span_id:350) (Token id:Id.Lit_Chars val:'\tgit add subdir/new &&\n' span_id:351) 
          (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:352) (Token id:Id.Lit_Chars val:'\tgit commit -m "subdir on master" subdir/new &&\n' span_id:353) 
          (Token id:Id.Lit_Chars val:'\tgit rm A.t &&\n' span_id:354) (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:355) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit commit -m "again subdir on master" &&\n'
            span_id: 356
          ) (Token id:Id.Lit_Chars val:'\tgit merge branch\n' span_id:357)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'use index-filter to move into a subdirectory' span_id:364))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:368) 
          (Token id:Id.Lit_Chars val:'\tgit branch directorymoved &&\n' span_id:369) (Token id:Id.Lit_Chars val:'\tgit filter-branch -f --index-filter \\\n' span_id:370) 
          (Token
            id: Id.Lit_Chars
            val: '\t\t "git ls-files -s | sed \\"s-\t-&newsubdir/-\\" |\n'
            span_id: 371
          ) (Token id:Id.Lit_Chars val:'\t          GIT_INDEX_FILE=\\$GIT_INDEX_FILE.new \\\n' span_id:372) 
          (Token
            id: Id.Lit_Chars
            val: '\t\t\tgit update-index --index-info &&\n'
            span_id: 373
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\t\t  mv \\"\\$GIT_INDEX_FILE.new\\" \\"\\$GIT_INDEX_FILE\\"" directorymoved &&\n'
            span_id: 374
          ) (Token id:Id.Lit_Chars val:'\tgit diff --exit-code HEAD directorymoved:newsubdir\n' span_id:375)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'stops when msg filter fails' span_id:382))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:386) 
          (Token id:Id.Lit_Chars val:'\told=$(git rev-parse HEAD) &&\n' span_id:387) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git filter-branch -f --msg-filter false HEAD &&\n'
            span_id: 388
          ) (Token id:Id.Lit_Chars val:'\ttest $old = $(git rev-parse HEAD) &&\n' span_id:389) 
          (Token id:Id.Lit_Chars val:'\trm -rf .git-rewrite\n' span_id:390)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'author information is preserved' span_id:397))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:401) 
          (Token id:Id.Lit_Chars val:'\t: > i &&\n' span_id:402) (Token id:Id.Lit_Chars val:'\tgit add i &&\n' span_id:403) 
          (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:404) (Token id:Id.Lit_Chars val:'\tGIT_AUTHOR_NAME="B V Uips" git commit -m bvuips &&\n' span_id:405) 
          (Token id:Id.Lit_Chars val:'\tgit branch preserved-author &&\n' span_id:406) (Token id:Id.Lit_Chars val:'\t(sane_unset GIT_AUTHOR_NAME &&\n' span_id:407) 
          (Token
            id: Id.Lit_Chars
            val: '\t git filter-branch -f --msg-filter "cat; \\\n'
            span_id: 408
          ) (Token id:Id.Lit_Chars val:'\t\t\ttest \\$GIT_COMMIT != $(git rev-parse master) || \\\n' span_id:409) 
          (Token id:Id.Lit_Chars val:'\t\t\techo Hallo" \\\n' span_id:410) (Token id:Id.Lit_Chars val:'\t\tpreserved-author) &&\n' span_id:411) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest 1 = $(git rev-list --author="B V Uips" preserved-author | wc -l)\n'
            span_id: 412
          )
        )
      }
    )
    (C {(test_expect_success)} {(DQ ("remove a certain author's commits"))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:423) 
          (Token id:Id.Lit_Chars val:'\techo i > i &&\n' span_id:424) (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:425) 
          (Token id:Id.Lit_Chars val:'\tgit commit -m i i &&\n' span_id:426) (Token id:Id.Lit_Chars val:'\tgit branch removed-author &&\n' span_id:427) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch -f --commit-filter "\\\n'
            span_id: 428
          ) (Token id:Id.Lit_Chars val:'\t\tif [ \\"\\$GIT_AUTHOR_NAME\\" = \\"B V Uips\\" ];\\\n' span_id:429) 
          (Token id:Id.Lit_Chars val:'\t\tthen\\\n' span_id:430) (Token id:Id.Lit_Chars val:'\t\t\tskip_commit \\"\\$@\\";\n' span_id:431) 
          (Token id:Id.Lit_Chars val:'\t\telse\\\n' span_id:432) (Token id:Id.Lit_Chars val:'\t\t\tgit commit-tree \\"\\$@\\";\\\n' span_id:433) 
          (Token id:Id.Lit_Chars val:'\t\tfi" removed-author &&\n' span_id:434) (Token id:Id.Lit_Chars val:'\tcnt1=$(git rev-list master | wc -l) &&\n' span_id:435) 
          (Token
            id: Id.Lit_Chars
            val: '\tcnt2=$(git rev-list removed-author | wc -l) &&\n'
            span_id: 436
          ) (Token id:Id.Lit_Chars val:'\ttest $cnt1 -eq $(($cnt2 + 1)) &&\n' span_id:437) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest 0 = $(git rev-list --author="B V Uips" removed-author | wc -l)\n'
            span_id: 438
          )
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'barf on invalid name' span_id:445))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:449) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git filter-branch -f master xy-problem &&\n'
            span_id: 450
          ) (Token id:Id.Lit_Chars val:'\ttest_must_fail git filter-branch -f HEAD^\n' span_id:451)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'"map" works in commit filter' span_id:458))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:462) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch -f --commit-filter "\\\n'
            span_id: 463
          ) (Token id:Id.Lit_Chars val:'\t\tparent=\\$(git rev-parse \\$GIT_COMMIT^) &&\n' span_id:464) 
          (Token id:Id.Lit_Chars val:'\t\tmapped=\\$(map \\$parent) &&\n' span_id:465) (Token id:Id.Lit_Chars val:'\t\tactual=\\$(echo \\"\\$@\\" | sed \\"s/^.*-p //\\") &&\n' span_id:466) 
          (Token id:Id.Lit_Chars val:'\t\ttest \\$mapped = \\$actual &&\n' span_id:467) (Token id:Id.Lit_Chars val:'\t\tgit commit-tree \\"\\$@\\";" master~2..master &&\n' span_id:468) 
          (Token id:Id.Lit_Chars val:'\tgit rev-parse --verify master\n' span_id:469)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'Name needing quotes' span_id:476))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:480) (Token id:Id.Lit_Chars val:'\n' span_id:481) 
          (Token id:Id.Lit_Chars val:'\tgit checkout -b rerere A &&\n' span_id:482) (Token id:Id.Lit_Chars val:'\tmkdir foo &&\n' span_id:483) 
          (Token
            id: Id.Lit_Chars
            val: '\tname="\xe3\x82\x8c\xe3\x82\x8c\xe3\x82\x8c" &&\n'
            span_id: 484
          ) (Token id:Id.Lit_Chars val:'\t>foo/$name &&\n' span_id:485) 
          (Token id:Id.Lit_Chars val:'\tgit add foo &&\n' span_id:486) (Token id:Id.Lit_Chars val:'\tgit commit -m "Adding a file" &&\n' span_id:487) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch --tree-filter "rm -fr foo" &&\n'
            span_id: 488
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git ls-files --error-unmatch "foo/$name" &&\n'
            span_id: 489
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest $(git rev-parse --verify rerere) != $(git rev-parse --verify A)\n'
            span_id: 490
          ) (Token id:Id.Lit_Chars val:'\n' span_id:491)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'Subdirectory filter with disappearing trees' span_id:498))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:502) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:503) (Token id:Id.Lit_Chars val:'\tgit checkout master &&\n' span_id:504) 
          (Token id:Id.Lit_Chars val:'\n' span_id:505) (Token id:Id.Lit_Chars val:'\tmkdir foo &&\n' span_id:506) 
          (Token id:Id.Lit_Chars val:'\ttouch foo/bar &&\n' span_id:507) (Token id:Id.Lit_Chars val:'\tgit add foo &&\n' span_id:508) 
          (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:509) (Token id:Id.Lit_Chars val:'\tgit commit -m "Adding foo" &&\n' span_id:510) 
          (Token id:Id.Lit_Chars val:'\n' span_id:511) (Token id:Id.Lit_Chars val:'\tgit rm -r foo &&\n' span_id:512) 
          (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:513) (Token id:Id.Lit_Chars val:'\tgit commit -m "Removing foo" &&\n' span_id:514) 
          (Token id:Id.Lit_Chars val:'\n' span_id:515) (Token id:Id.Lit_Chars val:'\tmkdir foo &&\n' span_id:516) 
          (Token id:Id.Lit_Chars val:'\ttouch foo/bar &&\n' span_id:517) (Token id:Id.Lit_Chars val:'\tgit add foo &&\n' span_id:518) 
          (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:519) (Token id:Id.Lit_Chars val:'\tgit commit -m "Re-adding foo" &&\n' span_id:520) 
          (Token id:Id.Lit_Chars val:'\n' span_id:521) (Token id:Id.Lit_Chars val:'\tgit filter-branch -f --subdirectory-filter foo &&\n' span_id:522) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest $(git rev-list master | wc -l) = 3\n'
            span_id: 523
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'Tag name filtering retains tag message' span_id:530))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:534) 
          (Token id:Id.Lit_Chars val:'\tgit tag -m atag T &&\n' span_id:535) (Token id:Id.Lit_Chars val:'\tgit cat-file tag T > expect &&\n' span_id:536) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch -f --tag-name-filter cat &&\n'
            span_id: 537
          ) (Token id:Id.Lit_Chars val:'\tgit cat-file tag T > actual &&\n' span_id:538) 
          (Token id:Id.Lit_Chars val:'\ttest_cmp expect actual\n' span_id:539)
        )
      }
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:faux_gpg_tag)
          op: assign_op.Equal
          rhs: 
            {
              (SQ (Token id:Id.Lit_Chars val:'object XXXXXX\n' span_id:545) 
                (Token id:Id.Lit_Chars val:'type commit\n' span_id:546) (Token id:Id.Lit_Chars val:'tag S\n' span_id:547) 
                (Token
                  id: Id.Lit_Chars
                  val: 'tagger T A Gger <tagger@example.com> 1206026339 -0500\n'
                  span_id: 548
                ) (Token id:Id.Lit_Chars val:'\n' span_id:549) 
                (Token
                  id: Id.Lit_Chars
                  val: 'This is a faux gpg signed tag.\n'
                  span_id: 550
                ) (Token id:Id.Lit_Chars val:'-----BEGIN PGP SIGNATURE-----\n' span_id:551) 
                (Token
                  id: Id.Lit_Chars
                  val: 'Version: FauxGPG v0.0.0 (FAUX/Linux)\n'
                  span_id: 552
                ) (Token id:Id.Lit_Chars val:'\n' span_id:553) 
                (Token
                  id: Id.Lit_Chars
                  val: 'gdsfoewhxu/6l06f1kxyxhKdZkrcbaiOMtkJUA9ITAc1mlamh0ooasxkH1XwMbYQ\n'
                  span_id: 554
                ) (Token id:Id.Lit_Chars val:'acmwXaWET20H0GeAGP+7vow=\n' span_id:555) 
                (Token id:Id.Lit_Chars val:'=agpO\n' span_id:556) (Token id:Id.Lit_Chars val:'-----END PGP SIGNATURE-----\n' span_id:557)
              )
            }
          spids: [543]
        )
      ]
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'Tag name filtering strips gpg signature' span_id:563))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:567) 
          (Token id:Id.Lit_Chars val:'\tsha1=$(git rev-parse HEAD) &&\n' span_id:568) 
          (Token
            id: Id.Lit_Chars
            val: '\tsha1t=$(echo "$faux_gpg_tag" | sed -e s/XXXXXX/$sha1/ | git mktag) &&\n'
            span_id: 569
          ) (Token id:Id.Lit_Chars val:'\tgit update-ref "refs/tags/S" "$sha1t" &&\n' span_id:570) 
          (Token
            id: Id.Lit_Chars
            val: '\techo "$faux_gpg_tag" | sed -e s/XXXXXX/$sha1/ | head -n 6 > expect &&\n'
            span_id: 571
          ) (Token id:Id.Lit_Chars val:'\tgit filter-branch -f --tag-name-filter cat &&\n' span_id:572) 
          (Token id:Id.Lit_Chars val:'\tgit cat-file tag S > actual &&\n' span_id:573) (Token id:Id.Lit_Chars val:'\ttest_cmp expect actual\n' span_id:574)
        )
      }
    )
    (C {(test_expect_success)} {(GPG)} 
      {(SQ (Token id:Id.Lit_Chars val:'Filtering retains message of gpg signed commit' span_id:583))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:587) 
          (Token id:Id.Lit_Chars val:'\tmkdir gpg &&\n' span_id:588) (Token id:Id.Lit_Chars val:'\ttouch gpg/foo &&\n' span_id:589) 
          (Token id:Id.Lit_Chars val:'\tgit add gpg &&\n' span_id:590) (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:591) 
          (Token id:Id.Lit_Chars val:'\tgit commit -S -m "Adding gpg" &&\n' span_id:592) (Token id:Id.Lit_Chars val:'\n' span_id:593) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit log -1 --format="%s" > expect &&\n'
            span_id: 594
          ) (Token id:Id.Lit_Chars val:'\tgit filter-branch -f --msg-filter "cat" &&\n' span_id:595) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit log -1 --format="%s" > actual &&\n'
            span_id: 596
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp expect actual\n' span_id:597)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'Tag name filtering allows slashes in tag names' span_id:604))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:608) 
          (Token id:Id.Lit_Chars val:'\tgit tag -m tag-with-slash X/1 &&\n' span_id:609) (Token id:Id.Lit_Chars val:'\tgit cat-file tag X/1 | sed -e s,X/1,X/2, > expect &&\n' span_id:610) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch -f --tag-name-filter "echo X/2" &&\n'
            span_id: 611
          ) (Token id:Id.Lit_Chars val:'\tgit cat-file tag X/2 > actual &&\n' span_id:612) 
          (Token id:Id.Lit_Chars val:'\ttest_cmp expect actual\n' span_id:613)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'Prune empty commits' span_id:620))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:624) 
          (Token id:Id.Lit_Chars val:'\tgit rev-list HEAD > expect &&\n' span_id:625) (Token id:Id.Lit_Chars val:'\ttest_commit to_remove &&\n' span_id:626) 
          (Token
            id: Id.Lit_Chars
            val: 
'\tgit filter-branch -f --index-filter "git update-index --remove to_remove.t" --prune-empty HEAD &&\n'
            span_id: 627
          ) (Token id:Id.Lit_Chars val:'\tgit rev-list HEAD > actual &&\n' span_id:628) 
          (Token id:Id.Lit_Chars val:'\ttest_cmp expect actual\n' span_id:629)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'prune empty collapsed merges' span_id:636))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:640) 
          (Token id:Id.Lit_Chars val:'\ttest_config merge.ff false &&\n' span_id:641) (Token id:Id.Lit_Chars val:'\tgit rev-list HEAD >expect &&\n' span_id:642) 
          (Token id:Id.Lit_Chars val:'\ttest_commit to_remove_2 &&\n' span_id:643) (Token id:Id.Lit_Chars val:'\tgit reset --hard HEAD^ &&\n' span_id:644) 
          (Token id:Id.Lit_Chars val:'\ttest_merge non-ff to_remove_2 &&\n' span_id:645) 
          (Token
            id: Id.Lit_Chars
            val: 
'\tgit filter-branch -f --index-filter "git update-index --remove to_remove_2.t" --prune-empty HEAD &&\n'
            span_id: 646
          ) (Token id:Id.Lit_Chars val:'\tgit rev-list HEAD >actual &&\n' span_id:647) 
          (Token id:Id.Lit_Chars val:'\ttest_cmp expect actual\n' span_id:648)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'prune empty works even without index/tree filters'
            span_id: 655
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:659) 
          (Token id:Id.Lit_Chars val:'\tgit rev-list HEAD >expect &&\n' span_id:660) (Token id:Id.Lit_Chars val:'\tgit commit --allow-empty -m empty &&\n' span_id:661) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch -f --prune-empty HEAD &&\n'
            span_id: 662
          ) (Token id:Id.Lit_Chars val:'\tgit rev-list HEAD >actual &&\n' span_id:663) 
          (Token id:Id.Lit_Chars val:'\ttest_cmp expect actual\n' span_id:664)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'--remap-to-ancestor with filename filters' span_id:671))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:675) 
          (Token id:Id.Lit_Chars val:'\tgit checkout master &&\n' span_id:676) (Token id:Id.Lit_Chars val:'\tgit reset --hard A &&\n' span_id:677) 
          (Token id:Id.Lit_Chars val:'\ttest_commit add-foo foo 1 &&\n' span_id:678) (Token id:Id.Lit_Chars val:'\tgit branch moved-foo &&\n' span_id:679) 
          (Token id:Id.Lit_Chars val:'\ttest_commit add-bar bar a &&\n' span_id:680) (Token id:Id.Lit_Chars val:'\tgit branch invariant &&\n' span_id:681) 
          (Token
            id: Id.Lit_Chars
            val: '\torig_invariant=$(git rev-parse invariant) &&\n'
            span_id: 682
          ) (Token id:Id.Lit_Chars val:'\tgit branch moved-bar &&\n' span_id:683) 
          (Token id:Id.Lit_Chars val:'\ttest_commit change-foo foo 2 &&\n' span_id:684) (Token id:Id.Lit_Chars val:'\tgit filter-branch -f --remap-to-ancestor \\\n' span_id:685) 
          (Token id:Id.Lit_Chars val:'\t\tmoved-foo moved-bar A..master \\\n' span_id:686) (Token id:Id.Lit_Chars val:'\t\t-- -- foo &&\n' span_id:687) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest $(git rev-parse moved-foo) = $(git rev-parse moved-bar) &&\n'
            span_id: 688
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest $(git rev-parse moved-foo) = $(git rev-parse master^) &&\n'
            span_id: 689
          ) (Token id:Id.Lit_Chars val:'\ttest $orig_invariant = $(git rev-parse invariant)\n' span_id:690)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'automatic remapping to ancestor with filename filters'
            span_id: 697
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:701) 
          (Token id:Id.Lit_Chars val:'\tgit checkout master &&\n' span_id:702) (Token id:Id.Lit_Chars val:'\tgit reset --hard A &&\n' span_id:703) 
          (Token id:Id.Lit_Chars val:'\ttest_commit add-foo2 foo 1 &&\n' span_id:704) (Token id:Id.Lit_Chars val:'\tgit branch moved-foo2 &&\n' span_id:705) 
          (Token id:Id.Lit_Chars val:'\ttest_commit add-bar2 bar a &&\n' span_id:706) (Token id:Id.Lit_Chars val:'\tgit branch invariant2 &&\n' span_id:707) 
          (Token
            id: Id.Lit_Chars
            val: '\torig_invariant=$(git rev-parse invariant2) &&\n'
            span_id: 708
          ) (Token id:Id.Lit_Chars val:'\tgit branch moved-bar2 &&\n' span_id:709) 
          (Token id:Id.Lit_Chars val:'\ttest_commit change-foo2 foo 2 &&\n' span_id:710) (Token id:Id.Lit_Chars val:'\tgit filter-branch -f \\\n' span_id:711) 
          (Token
            id: Id.Lit_Chars
            val: '\t\tmoved-foo2 moved-bar2 A..master \\\n'
            span_id: 712
          ) (Token id:Id.Lit_Chars val:'\t\t-- -- foo &&\n' span_id:713) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest $(git rev-parse moved-foo2) = $(git rev-parse moved-bar2) &&\n'
            span_id: 714
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest $(git rev-parse moved-foo2) = $(git rev-parse master^) &&\n'
            span_id: 715
          ) (Token id:Id.Lit_Chars val:'\ttest $orig_invariant = $(git rev-parse invariant2)\n' span_id:716)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'setup submodule' span_id:723))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:727) 
          (Token id:Id.Lit_Chars val:'\trm -fr ?* .git &&\n' span_id:728) (Token id:Id.Lit_Chars val:'\tgit init &&\n' span_id:729) 
          (Token id:Id.Lit_Chars val:'\ttest_commit file &&\n' span_id:730) (Token id:Id.Lit_Chars val:'\tmkdir submod &&\n' span_id:731) 
          (Token id:Id.Lit_Chars val:'\tsubmodurl="$PWD/submod" &&\n' span_id:732) (Token id:Id.Lit_Chars val:'\t( cd submod &&\n' span_id:733) 
          (Token id:Id.Lit_Chars val:'\t  git init &&\n' span_id:734) (Token id:Id.Lit_Chars val:'\t  test_commit file-in-submod ) &&\n' span_id:735) 
          (Token id:Id.Lit_Chars val:'\tgit submodule add "$submodurl" &&\n' span_id:736) (Token id:Id.Lit_Chars val:'\tgit commit -m "added submodule" &&\n' span_id:737) 
          (Token id:Id.Lit_Chars val:'\ttest_commit add-file &&\n' span_id:738) (Token id:Id.Lit_Chars val:'\t( cd submod && test_commit add-in-submodule ) &&\n' span_id:739) 
          (Token id:Id.Lit_Chars val:'\tgit add submod &&\n' span_id:740) (Token id:Id.Lit_Chars val:'\tgit commit -m "changed submodule" &&\n' span_id:741) 
          (Token id:Id.Lit_Chars val:'\tgit branch original HEAD\n' span_id:742)
        )
      }
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:orig_head)
          op: assign_op.Equal
          rhs: 
            {
              (command_sub
                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:747)
                command_list: 
                  (command.CommandList
                    children: [(C {(git)} {(show-ref)} {(--hash)} {(--head)} {(HEAD)})]
                  )
              )
            }
          spids: [746]
        )
      ]
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'rewrite submodule with another content' span_id:763))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:767) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch --tree-filter "test -d submod && {\n'
            span_id: 768
          ) (Token id:Id.Lit_Chars val:'\t\t\t\t\t rm -rf submod &&\n' span_id:769) 
          (Token
            id: Id.Lit_Chars
            val: '\t\t\t\t\t git rm -rf --quiet submod &&\n'
            span_id: 770
          ) (Token id:Id.Lit_Chars val:'\t\t\t\t\t mkdir submod &&\n' span_id:771) 
          (Token id:Id.Lit_Chars val:'\t\t\t\t\t : > submod/file\n' span_id:772) (Token id:Id.Lit_Chars val:'\t\t\t\t\t } || :" HEAD &&\n' span_id:773) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest $orig_head != $(git show-ref --hash --head HEAD)\n'
            span_id: 774
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'replace submodule revision' span_id:781))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:785) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard original &&\n' span_id:786) (Token id:Id.Lit_Chars val:'\tgit filter-branch -f --tree-filter \\\n' span_id:787) 
          (Token
            id: Id.Lit_Chars
            val: '\t    "if git ls-files --error-unmatch -- submod > /dev/null 2>&1\n'
            span_id: 788
          ) 
          (Token
            id: Id.Lit_Chars
            val: 
'\t     then git update-index --cacheinfo 160000 0123456789012345678901234567890123456789 submod\n'
            span_id: 789
          ) (Token id:Id.Lit_Chars val:'\t     fi" HEAD &&\n' span_id:790) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest $orig_head != $(git show-ref --hash --head HEAD)\n'
            span_id: 791
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'filter commit message without trailing newline' span_id:798))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:802) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard original &&\n' span_id:803) 
          (Token
            id: Id.Lit_Chars
            val: '\tcommit=$(printf "no newline" | git commit-tree HEAD^{tree}) &&\n'
            span_id: 804
          ) (Token id:Id.Lit_Chars val:'\tgit update-ref refs/heads/no-newline $commit &&\n' span_id:805) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch -f refs/heads/no-newline &&\n'
            span_id: 806
          ) (Token id:Id.Lit_Chars val:'\techo $commit >expect &&\n' span_id:807) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit rev-parse refs/heads/no-newline >actual &&\n'
            span_id: 808
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp expect actual\n' span_id:809)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'tree-filter deals with object name vs pathname ambiguity'
            span_id: 816
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:820) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_when_finished "git reset --hard original" &&\n'
            span_id: 821
          ) (Token id:Id.Lit_Chars val:'\tambiguous=$(git rev-list -1 HEAD) &&\n' span_id:822) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit filter-branch --tree-filter "mv file.t $ambiguous" HEAD^.. &&\n'
            span_id: 823
          ) (Token id:Id.Lit_Chars val:'\tgit show HEAD:$ambiguous\n' span_id:824)
        )
      }
    )
    (C {(test_done)})
  ]
)