(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: {(SQ <'test log -L'>)}
          spids: [4]
        )
      ]
    )
    (C {<.>} {<./test-lib.sh>})
    (C {<test_expect_success>} {(SQ <'setup (import history)'>)} 
      {
        (SQ <'\n'> <'\tgit fast-import < "$TEST_DIRECTORY"/t4211/history.export &&\n'> 
          <'\tgit reset --hard\n'>
        )
      }
    )
    (command.ShFunction
      name: canned_test_1
      body: 
        (command.BraceGroup
          children: [
            (C {<test_expect_> ($ Id.VSub_Number '$1')} {(DQ ($ Id.VSub_Number '$2'))} 
              {
                (DQ <'\n'> <'\t\tgit log '> ($ Id.VSub_Number '$2') <' >actual &&\n'> <'\t\ttest_cmp '> 
                  (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\$'>) <TEST_DIRECTORY> 
                  (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\"'>) </t4211/expect.> ($ Id.VSub_Number '$3') <' actual\n'> <'\t'>
                )
              }
            )
          ]
        )
    )
    (command.ShFunction
      name: canned_test
      body: 
        (command.BraceGroup
          children: [(C {<canned_test_1>} {<success>} {(DQ ($ Id.VSub_At '$@'))})]
        )
    )
    (command.ShFunction
      name: canned_test_failure
      body: 
        (command.BraceGroup
          children: [(C {<canned_test_1>} {<failure>} {(DQ ($ Id.VSub_At '$@'))})]
        )
    )
    (command.ShFunction
      name: test_bad_opts
      body: 
        (command.BraceGroup
          children: [
            (C {<test_expect_success>} {(DQ <'invalid args: '> ($ Id.VSub_Number '$1'))} 
              {
                (DQ <'\n'> <'\t\ttest_must_fail git log '> ($ Id.VSub_Number '$1') <' 2>errors &&\n'> 
                  <"\t\tgrep '"> ($ Id.VSub_Number '$2') <"' errors\n"> <'\t'>
                )
              }
            )
          ]
        )
    )
    (C {<canned_test>} {(DQ <'-L 4,12:a.c simple'>)} {<simple-f>})
    (C {<canned_test>} {(DQ <'-L 4,+9:a.c simple'>)} {<simple-f>})
    (C {<canned_test>} {(DQ <"-L '/long f/,/^}/:a.c' simple">)} {<simple-f>})
    (C {<canned_test>} {(DQ <'-L :f:a.c simple'>)} {<simple-f-to-main>})
    (C {<canned_test>} {(DQ <"-L '/main/,/^}/:a.c' simple">)} {<simple-main>})
    (C {<canned_test>} {(DQ <'-L :main:a.c simple'>)} {<simple-main-to-end>})
    (C {<canned_test>} {(DQ <'-L 1,+4:a.c simple'>)} {<beginning-of-file>})
    (C {<canned_test>} {(DQ <'-L 20:a.c simple'>)} {<end-of-file>})
    (C {<canned_test>} {(DQ <"-L '/long f/',/^}/:a.c -L /main/,/^}/:a.c simple">)} {<two-ranges>})
    (C {<canned_test>} {(DQ <'-L 24,+1:a.c simple'>)} {<vanishes-early>})
    (C {<canned_test>} {(DQ <"-M -L '/long f/,/^}/:b.c' move-support">)} {<move-support-f>})
    (C {<canned_test>} {(DQ <"-M -L ':f:b.c' parallel-change">)} {<parallel-change-f-to-main>})
    (C {<canned_test>} {(DQ <'-L 4,12:a.c -L :main:a.c simple'>)} {<multiple>})
    (C {<canned_test>} {(DQ <'-L 4,18:a.c -L ^:main:a.c simple'>)} {<multiple-overlapping>})
    (C {<canned_test>} {(DQ <'-L :main:a.c -L 4,18:a.c simple'>)} {<multiple-overlapping>})
    (C {<canned_test>} {(DQ <'-L 4:a.c -L 8,12:a.c simple'>)} {<multiple-superset>})
    (C {<canned_test>} {(DQ <'-L 8,12:a.c -L 4:a.c simple'>)} {<multiple-superset>})
    (C {<test_bad_opts>} {(DQ <-L>)} {(DQ <'switch.*requires a value'>)})
    (C {<test_bad_opts>} {(DQ <'-L b.c'>)} {(DQ <'argument not .start,end:file'>)})
    (C {<test_bad_opts>} {(DQ <'-L 1:'>)} {(DQ <'argument not .start,end:file'>)})
    (C {<test_bad_opts>} {(DQ <'-L 1:nonexistent'>)} {(DQ <'There is no path'>)})
    (C {<test_bad_opts>} {(DQ <'-L 1:simple'>)} {(DQ <'There is no path'>)})
    (C {<test_bad_opts>} {(DQ <"-L '/foo:b.c'">)} {(DQ <'argument not .start,end:file'>)})
    (C {<test_bad_opts>} {(DQ <'-L 1000:b.c'>)} {(DQ <'has only.*lines'>)})
    (C {<test_bad_opts>} {(DQ <'-L 1,1000:b.c'>)} {(DQ <'has only.*lines'>)})
    (C {<test_bad_opts>} {(DQ <'-L :b.c'>)} {(DQ <'argument not .start,end:file'>)})
    (C {<test_bad_opts>} {(DQ <'-L :foo:b.c'>)} {(DQ <'no match'>)})
    (C {<test_expect_success>} {(SQ <'-L X (X == nlines)'>)} 
      {(SQ <'\n'> <'\tn=$(wc -l <b.c) &&\n'> <'\tgit log -L $n:b.c\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'-L X (X == nlines + 1)'>)} 
      {(SQ <'\n'> <'\tn=$(expr $(wc -l <b.c) + 1) &&\n'> <'\ttest_must_fail git log -L $n:b.c\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'-L X (X == nlines + 2)'>)} 
      {(SQ <'\n'> <'\tn=$(expr $(wc -l <b.c) + 2) &&\n'> <'\ttest_must_fail git log -L $n:b.c\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'-L ,Y (Y == nlines)'>)} 
      {(SQ <'\n'> <'\tn=$(printf "%d" $(wc -l <b.c)) &&\n'> <'\tgit log -L ,$n:b.c\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'-L ,Y (Y == nlines + 1)'>)} 
      {(SQ <'\n'> <'\tn=$(expr $(wc -l <b.c) + 1) &&\n'> <'\ttest_must_fail git log -L ,$n:b.c\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'-L ,Y (Y == nlines + 2)'>)} 
      {(SQ <'\n'> <'\tn=$(expr $(wc -l <b.c) + 2) &&\n'> <'\ttest_must_fail git log -L ,$n:b.c\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'-L with --first-parent and a merge'>)} 
      {(SQ <'\n'> <'\tgit checkout parallel-change &&\n'> <'\tgit log --first-parent -L 1,1:b.c\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'-L with --output'>)} 
      {
        (SQ <'\n'> <'\tgit checkout parallel-change &&\n'> 
          <'\tgit log --output=log -L :main:b.c >output &&\n'> <'\ttest ! -s output &&\n'> <'\ttest_line_count = 70 log\n'>
        )
      }
    )
    (C {<test_done>})
  ]
)