(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: 
        (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: (BraceGroup children:[(C {<canned_test_1>} {<success>} {(DQ ($ Id.VSub_At '$@'))})])
    )
    (command.ShFunction
      name: canned_test_failure
      body: (BraceGroup children:[(C {<canned_test_1>} {<failure>} {(DQ ($ Id.VSub_At '$@'))})])
    )
    (command.ShFunction
      name: test_bad_opts
      body: 
        (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>})
  ]
)