(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:'checkout ' span_id:6))}
          spids: [4]
        )
      ]
    )
    (C {(.)} {(./test-lib.sh)})
    (command.ShFunction
      name: do_checkout
      body: 
        (command.BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp]
              children: [
                (command.ShAssignment
                  pairs: [
                    (assign_pair
                      lhs: (sh_lhs_expr.Name name:exp_branch)
                      op: assign_op.Equal
                      rhs: {($ Id.VSub_Number '$1')}
                      spids: [46]
                    )
                  ]
                )
                (command.ShAssignment
                  pairs: [
                    (assign_pair
                      lhs: (sh_lhs_expr.Name name:exp_ref)
                      op: assign_op.Equal
                      rhs: {(DQ (refs/heads/) ($ Id.VSub_DollarName '$exp_branch'))}
                      spids: [52]
                    )
                  ]
                )
                (command.ShAssignment
                  pairs: [
                    (assign_pair
                      lhs: (sh_lhs_expr.Name name:exp_sha)
                      op: assign_op.Equal
                      rhs: 
                        {
                          (braced_var_sub
                            token: (Token id:Id.VSub_Number val:2 span_id:68)
                            suffix_op: 
                              (suffix_op.Unary
                                op_id: Id.VTest_ColonHyphen
                                arg_word: 
                                  {
                                    (command_sub
                                      left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:70)
                                      command_list: 
                                        (command.CommandList
                                          children: [(C {(git)} {(rev-parse)} {(--verify)} {(HEAD)})]
                                        )
                                    )
                                  }
                              )
                          )
                        }
                      spids: [66]
                    )
                  ]
                )
                (command.If
                  arms: [
                    (if_arm
                      cond: [
                        (command.Sentence
                          child: 
                            (C {(Id.Lit_LBracket '[')} {(-z)} {(DQ ($ Id.VSub_Number '$3'))} 
                              {(Id.Lit_RBracket ']')}
                            )
                          terminator: (Token id:Id.Op_Semi val:';' span_id:100)
                        )
                      ]
                      action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:opts)
                              op: assign_op.Equal
                              rhs: {(DQ (-b))}
                              spids: [105]
                            )
                          ]
                        )
                      ]
                      spids: [89 102]
                    )
                  ]
                  else_action: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:opts)
                          op: assign_op.Equal
                          rhs: {(DQ ($ Id.VSub_Number '$3'))}
                          spids: [114]
                        )
                      ]
                    )
                  ]
                )
              ]
            )
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp]
              children: [
                (C {(git)} {(checkout)} {($ Id.VSub_DollarName '$opts')} 
                  {($ Id.VSub_DollarName '$exp_branch')} {($ Id.VSub_DollarName '$exp_sha')}
                )
                (C {(test)} {($ Id.VSub_DollarName '$exp_ref')} {(Id.Lit_Equals '=')} 
                  {
                    (command_sub
                      left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:144)
                      command_list: 
                        (command.CommandList
                          children: [(C {(git)} {(rev-parse)} {(--symbolic-full-name)} {(HEAD)})]
                        )
                    )
                  }
                )
                (C {(test)} {($ Id.VSub_DollarName '$exp_sha')} {(Id.Lit_Equals '=')} 
                  {
                    (command_sub
                      left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:163)
                      command_list: 
                        (command.CommandList
                          children: [(C {(git)} {(rev-parse)} {(--verify)} {(HEAD)})]
                        )
                    )
                  }
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: test_dirty_unmergeable
      body: 
        (command.BraceGroup
          children: [
            (command.Pipeline
              children: [
                (command.Simple
                  words: [{(git)} {(diff)} {(--exit-code)}]
                  redirects: [
                    (redir.Redir
                      op: (Token id:Id.Redir_Great val:'>' span_id:191)
                      fd: -1
                      arg_word: {(/dev/null)}
                    )
                  ]
                )
              ]
              negated: T
            )
          ]
        )
    )
    (command.ShFunction
      name: setup_dirty_unmergeable
      body: 
        (command.BraceGroup
          children: [
            (command.Simple
              words: [{(echo)} {(change2)}]
              redirects: [
                (redir.Redir
                  op: (Token id:Id.Redir_DGreat val:'>>' span_id:206)
                  fd: -1
                  arg_word: {(file1)}
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: test_dirty_mergeable
      body: 
        (command.BraceGroup
          children: [
            (command.Pipeline
              children: [
                (command.Simple
                  words: [{(git)} {(diff)} {(--cached)} {(--exit-code)}]
                  redirects: [
                    (redir.Redir
                      op: (Token id:Id.Redir_Great val:'>' span_id:231)
                      fd: -1
                      arg_word: {(/dev/null)}
                    )
                  ]
                )
              ]
              negated: T
            )
          ]
        )
    )
    (command.ShFunction
      name: setup_dirty_mergeable
      body: 
        (command.BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp]
              children: [
                (command.Simple
                  words: [{(echo)} {(file2)}]
                  redirects: [
                    (redir.Redir
                      op: (Token id:Id.Redir_Great val:'>' span_id:246)
                      fd: -1
                      arg_word: {(file2)}
                    )
                  ]
                )
                (C {(git)} {(add)} {(file2)})
              ]
            )
          ]
        )
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:setup span_id:266))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:270) 
          (Token id:Id.Lit_Chars val:'\ttest_commit initial file1 &&\n' span_id:271) (Token id:Id.Lit_Chars val:'\tHEAD1=$(git rev-parse --verify HEAD) &&\n' span_id:272) 
          (Token id:Id.Lit_Chars val:'\n' span_id:273) (Token id:Id.Lit_Chars val:'\ttest_commit change1 file1 &&\n' span_id:274) 
          (Token
            id: Id.Lit_Chars
            val: '\tHEAD2=$(git rev-parse --verify HEAD) &&\n'
            span_id: 275
          ) (Token id:Id.Lit_Chars val:'\n' span_id:276) 
          (Token id:Id.Lit_Chars val:'\tgit branch -m branch1\n' span_id:277)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'checkout -b to a new branch, set to HEAD' span_id:284))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:288) 
          (Token id:Id.Lit_Chars val:'\tdo_checkout branch2\n' span_id:289)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -b to a new branch, set to an explicit ref'
            span_id: 296
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:300) 
          (Token id:Id.Lit_Chars val:'\tgit checkout branch1 &&\n' span_id:301) (Token id:Id.Lit_Chars val:'\tgit branch -D branch2 &&\n' span_id:302) 
          (Token id:Id.Lit_Chars val:'\n' span_id:303) (Token id:Id.Lit_Chars val:'\tdo_checkout branch2 $HEAD1\n' span_id:304)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -b to a new branch with unmergeable changes fails'
            span_id: 311
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:315) 
          (Token id:Id.Lit_Chars val:'\tgit checkout branch1 &&\n' span_id:316) (Token id:Id.Lit_Chars val:'\n' span_id:317) 
          (Token id:Id.Lit_Chars val:'\t# clean up from previous test\n' span_id:318) (Token id:Id.Lit_Chars val:'\tgit branch -D branch2 &&\n' span_id:319) 
          (Token id:Id.Lit_Chars val:'\n' span_id:320) (Token id:Id.Lit_Chars val:'\tsetup_dirty_unmergeable &&\n' span_id:321) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail do_checkout branch2 $HEAD1 &&\n'
            span_id: 322
          ) (Token id:Id.Lit_Chars val:'\ttest_dirty_unmergeable\n' span_id:323)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -f -b to a new branch with unmergeable changes discards changes'
            span_id: 330
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:334) 
          (Token id:Id.Lit_Chars val:'\t# still dirty and on branch1\n' span_id:335) (Token id:Id.Lit_Chars val:'\tdo_checkout branch2 $HEAD1 "-f -b" &&\n' span_id:336) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail test_dirty_unmergeable\n'
            span_id: 337
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -b to a new branch preserves mergeable changes'
            span_id: 344
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:348) 
          (Token id:Id.Lit_Chars val:'\tgit checkout branch1 &&\n' span_id:349) (Token id:Id.Lit_Chars val:'\n' span_id:350) 
          (Token id:Id.Lit_Chars val:'\t# clean up from previous test\n' span_id:351) (Token id:Id.Lit_Chars val:'\tgit branch -D branch2 &&\n' span_id:352) 
          (Token id:Id.Lit_Chars val:'\n' span_id:353) (Token id:Id.Lit_Chars val:'\tsetup_dirty_mergeable &&\n' span_id:354) 
          (Token id:Id.Lit_Chars val:'\tdo_checkout branch2 $HEAD1 &&\n' span_id:355) (Token id:Id.Lit_Chars val:'\ttest_dirty_mergeable\n' span_id:356)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -f -b to a new branch with mergeable changes discards changes'
            span_id: 363
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:367) 
          (Token id:Id.Lit_Chars val:'\t# clean up from previous test\n' span_id:368) (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:369) 
          (Token id:Id.Lit_Chars val:'\n' span_id:370) (Token id:Id.Lit_Chars val:'\tgit checkout branch1 &&\n' span_id:371) 
          (Token id:Id.Lit_Chars val:'\n' span_id:372) (Token id:Id.Lit_Chars val:'\t# clean up from previous test\n' span_id:373) 
          (Token id:Id.Lit_Chars val:'\tgit branch -D branch2 &&\n' span_id:374) (Token id:Id.Lit_Chars val:'\n' span_id:375) 
          (Token id:Id.Lit_Chars val:'\tsetup_dirty_mergeable &&\n' span_id:376) (Token id:Id.Lit_Chars val:'\tdo_checkout branch2 $HEAD1 "-f -b" &&\n' span_id:377) 
          (Token id:Id.Lit_Chars val:'\ttest_must_fail test_dirty_mergeable\n' span_id:378)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'checkout -b to an existing branch fails' span_id:385))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:389) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard HEAD &&\n' span_id:390) (Token id:Id.Lit_Chars val:'\n' span_id:391) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail do_checkout branch2 $HEAD2\n'
            span_id: 392
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -b to @{-1} fails with the right branch name'
            span_id: 399
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:403) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard HEAD &&\n' span_id:404) (Token id:Id.Lit_Chars val:'\tgit checkout branch1 &&\n' span_id:405) 
          (Token id:Id.Lit_Chars val:'\tgit checkout branch2 &&\n' span_id:406) (Token id:Id.Lit_Chars val:'\techo  >expect "fatal: A branch named ' span_id:407)
        ) (word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:"\\'" span_id:409)) 
        (SQ (Token id:Id.Lit_Chars val:branch1 span_id:411)) (word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:"\\'" span_id:413)) 
        (SQ (Token id:Id.Lit_Chars val:' already exists." &&\n' span_id:415) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail git checkout -b @{-1} 2>actual &&\n'
            span_id: 416
          ) (Token id:Id.Lit_Chars val:'\ttest_i18ncmp expect actual\n' span_id:417)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -B to an existing branch resets branch to HEAD'
            span_id: 424
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:428) 
          (Token id:Id.Lit_Chars val:'\tgit checkout branch1 &&\n' span_id:429) (Token id:Id.Lit_Chars val:'\n' span_id:430) 
          (Token id:Id.Lit_Chars val:'\tdo_checkout branch2 "" -B\n' span_id:431)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -B to an existing branch from detached HEAD resets branch to HEAD'
            span_id: 438
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:442) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit checkout $(git rev-parse --verify HEAD) &&\n'
            span_id: 443
          ) (Token id:Id.Lit_Chars val:'\n' span_id:444) 
          (Token id:Id.Lit_Chars val:'\tdo_checkout branch2 "" -B\n' span_id:445)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -B to an existing branch with an explicit ref resets branch to that ref'
            span_id: 452
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:456) 
          (Token id:Id.Lit_Chars val:'\tgit checkout branch1 &&\n' span_id:457) (Token id:Id.Lit_Chars val:'\n' span_id:458) 
          (Token id:Id.Lit_Chars val:'\tdo_checkout branch2 $HEAD1 -B\n' span_id:459)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -B to an existing branch with unmergeable changes fails'
            span_id: 466
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:470) 
          (Token id:Id.Lit_Chars val:'\tgit checkout branch1 &&\n' span_id:471) (Token id:Id.Lit_Chars val:'\n' span_id:472) 
          (Token id:Id.Lit_Chars val:'\tsetup_dirty_unmergeable &&\n' span_id:473) (Token id:Id.Lit_Chars val:'\ttest_must_fail do_checkout branch2 $HEAD1 -B &&\n' span_id:474) 
          (Token id:Id.Lit_Chars val:'\ttest_dirty_unmergeable\n' span_id:475)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -f -B to an existing branch with unmergeable changes discards changes'
            span_id: 482
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:486) 
          (Token id:Id.Lit_Chars val:'\t# still dirty and on branch1\n' span_id:487) (Token id:Id.Lit_Chars val:'\tdo_checkout branch2 $HEAD1 "-f -B" &&\n' span_id:488) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail test_dirty_unmergeable\n'
            span_id: 489
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -B to an existing branch preserves mergeable changes'
            span_id: 496
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:500) 
          (Token id:Id.Lit_Chars val:'\tgit checkout branch1 &&\n' span_id:501) (Token id:Id.Lit_Chars val:'\n' span_id:502) 
          (Token id:Id.Lit_Chars val:'\tsetup_dirty_mergeable &&\n' span_id:503) (Token id:Id.Lit_Chars val:'\tdo_checkout branch2 $HEAD1 -B &&\n' span_id:504) 
          (Token id:Id.Lit_Chars val:'\ttest_dirty_mergeable\n' span_id:505)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'checkout -f -B to an existing branch with mergeable changes discards changes'
            span_id: 512
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:516) 
          (Token id:Id.Lit_Chars val:'\t# clean up from previous test\n' span_id:517) (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:518) 
          (Token id:Id.Lit_Chars val:'\n' span_id:519) (Token id:Id.Lit_Chars val:'\tgit checkout branch1 &&\n' span_id:520) 
          (Token id:Id.Lit_Chars val:'\n' span_id:521) (Token id:Id.Lit_Chars val:'\tsetup_dirty_mergeable &&\n' span_id:522) 
          (Token
            id: Id.Lit_Chars
            val: '\tdo_checkout branch2 $HEAD1 "-f -B" &&\n'
            span_id: 523
          ) (Token id:Id.Lit_Chars val:'\ttest_must_fail test_dirty_mergeable\n' span_id:524)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'checkout -b <describe>' span_id:531))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:535) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit tag -f -m "First commit" initial initial &&\n'
            span_id: 536
          ) (Token id:Id.Lit_Chars val:'\tgit checkout -f change1 &&\n' span_id:537) 
          (Token id:Id.Lit_Chars val:'\tname=$(git describe) &&\n' span_id:538) (Token id:Id.Lit_Chars val:'\tgit checkout -b $name &&\n' span_id:539) 
          (Token id:Id.Lit_Chars val:'\tgit diff --exit-code change1 &&\n' span_id:540) (Token id:Id.Lit_Chars val:'\techo "refs/heads/$name" >expect &&\n' span_id:541) 
          (Token id:Id.Lit_Chars val:'\tgit symbolic-ref HEAD >actual &&\n' span_id:542) (Token id:Id.Lit_Chars val:'\ttest_cmp expect actual\n' span_id:543)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'checkout -B to the current branch works' span_id:550))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:554) 
          (Token id:Id.Lit_Chars val:'\tgit checkout branch1 &&\n' span_id:555) (Token id:Id.Lit_Chars val:'\tgit checkout -B branch1-scratch &&\n' span_id:556) 
          (Token id:Id.Lit_Chars val:'\n' span_id:557) (Token id:Id.Lit_Chars val:'\tsetup_dirty_mergeable &&\n' span_id:558) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit checkout -B branch1-scratch initial &&\n'
            span_id: 559
          ) (Token id:Id.Lit_Chars val:'\ttest_dirty_mergeable\n' span_id:560)
        )
      }
    )
    (C {(test_done)})
  ]
)