(CommandList
  children: [
    (Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (LhsName name:test_description)
          op: Equal
          rhs: {(SQ <"diff function context">)}
          spids: [4]
        )
      ]
      spids: [4]
    )
    (C {(.)} {(./test-lib.sh)})
    (Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (LhsName name:dir)
          op: Equal
          rhs: {(DQ ($ VSub_Name "$TEST_DIRECTORY") (/t4051))}
          spids: [15]
        )
      ]
      spids: [15]
    )
    (FuncDef
      name: commit_and_tag
      body: 
        (BraceGroup
          children: [
            (AndOr
              children: [
                (Assignment
                  keyword: Assign_None
                  pairs: [
                    (assign_pair
                      lhs: (LhsName name:tag)
                      op: Equal
                      rhs: {($ VSub_Number "$1")}
                      spids: [30]
                    )
                  ]
                  spids: [30]
                )
                (AndOr
                  children: [
                    (C {(shift)})
                    (AndOr
                      children: [
                        (C {(git)} {(add)} {(DQ ($ VSub_At "$@"))})
                        (AndOr
                          children: [
                            (C {(test_tick)})
                            (AndOr
                              children: [
                                (C {(git)} {(commit)} {(-m)} {(DQ ($ VSub_Name "$tag"))})
                                (C {(git)} {(tag)} {(DQ ($ VSub_Name "$tag"))})
                              ]
                              op_id: Op_DAmp
                            )
                          ]
                          op_id: Op_DAmp
                        )
                      ]
                      op_id: Op_DAmp
                    )
                  ]
                  op_id: Op_DAmp
                )
              ]
              op_id: Op_DAmp
            )
          ]
          spids: [27]
        )
      spids: [22 26]
    )
    (FuncDef
      name: first_context_line
      body: 
        (BraceGroup
          children: [
            (C {(awk)} {(SQ <"\n"> <"\t\tfound {print; exit}\n"> <"\t\t/^@@/ {found = 1}\n"> <"\t">)})
          ]
          spids: [86]
        )
      spids: [81 85]
    )
    (FuncDef
      name: last_context_line
      body: 
        (BraceGroup
          children: [(C {(sed)} {(-ne)} {(EscapedLiteralPart token:<Lit_EscapedChar "\\$">) (p)})]
          spids: [106]
        )
      spids: [101 105]
    )
    (FuncDef
      name: check_diff
      body: 
        (BraceGroup
          children: [
            (Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (LhsName name:name)
                  op: Equal
                  rhs: {($ VSub_Number "$1")}
                  spids: [127]
                )
              ]
              spids: [127]
            )
            (Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (LhsName name:desc)
                  op: Equal
                  rhs: {($ VSub_Number "$2")}
                  spids: [131]
                )
              ]
              spids: [131]
            )
            (Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (LhsName name:options)
                  op: Equal
                  rhs: {(DQ ("-W ") ($ VSub_Number "$3"))}
                  spids: [135]
                )
              ]
              spids: [135]
            )
            (C {(test_expect_success)} {(DQ ($ VSub_Name "$desc"))} 
              {(SQ <"\n"> <"\t\tgit diff $options \"$name^\" \"$name\" >\"$name.diff\"\n"> <"\t">)}
            )
            (C {(test_expect_success)} {(SQ <" diff applies">)} 
              {
                (SQ <"\n"> <"\t\ttest_when_finished \"git reset --hard\" &&\n"> 
                  <"\t\tgit checkout --detach \"$name^\" &&\n"> <"\t\tgit apply --index \"$name.diff\" &&\n"> <"\t\tgit diff --exit-code \"$name\"\n"> <"\t">
                )
              }
            )
          ]
          spids: [124]
        )
      spids: [119 123]
    )
    (C {(test_expect_success)} {(SQ <setup>)} 
      {
        (SQ <"\n"> 
          <"\tcat \"$dir/includes.c\" \"$dir/dummy.c\" \"$dir/dummy.c\" \"$dir/hello.c\" \\\n"> <"\t\t\"$dir/dummy.c\" \"$dir/dummy.c\" >file.c &&\n"> <"\tcommit_and_tag initial file.c &&\n"> <"\n"> 
          <"\tgrep -v \"delete me from hello\" <file.c >file.c.new &&\n"> <"\tmv file.c.new file.c &&\n"> <"\tcommit_and_tag changed_hello file.c &&\n"> <"\n"> 
          <"\tgrep -v \"delete me from includes\" <file.c >file.c.new &&\n"> <"\tmv file.c.new file.c &&\n"> <"\tcommit_and_tag changed_includes file.c &&\n"> <"\n"> 
          <"\tcat \"$dir/appended1.c\" >>file.c &&\n"> <"\tcommit_and_tag appended file.c &&\n"> <"\n"> <"\tcat \"$dir/appended2.c\" >>file.c &&\n"> 
          <"\tcommit_and_tag extended file.c &&\n"> <"\n"> <"\tgrep -v \"Begin of second part\" <file.c >file.c.new &&\n"> <"\tmv file.c.new file.c &&\n"> 
          <"\tcommit_and_tag long_common_tail file.c &&\n"> <"\n"> <"\tgit checkout initial &&\n"> <"\tcat \"$dir/hello.c\" \"$dir/dummy.c\" >file.c &&\n"> 
          <"\tcommit_and_tag hello_dummy file.c &&\n"> <"\n"> <"\t# overlap function context of 1st change and -u context of 2nd change\n"> 
          <"\tgrep -v \"delete me from hello\" <\"$dir/hello.c\" >file.c &&\n"> <"\tsed 2p <\"$dir/dummy.c\" >>file.c &&\n"> <"\tcommit_and_tag changed_hello_dummy file.c &&\n"> 
          <"\n"> <"\tgit checkout initial &&\n"> <"\tgrep -v \"delete me from hello\" <file.c >file.c.new &&\n"> 
          <"\tmv file.c.new file.c &&\n"> <"\tcat \"$dir/appended1.c\" >>file.c &&\n"> <"\tcommit_and_tag changed_hello_appended file.c\n">
        )
      }
    )
    (C {(check_diff)} {(changed_hello)} {(SQ <"changed function">)})
    (C {(test_expect_success)} {(SQ <" context includes begin">)} 
      {(SQ <"\n"> <"\tgrep \"^ .*Begin of hello\" changed_hello.diff\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context includes end">)} 
      {(SQ <"\n"> <"\tgrep \"^ .*End of hello\" changed_hello.diff\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context does not include other functions">)} 
      {(SQ <"\n"> <"\ttest $(grep -c \"^[ +-].*Begin\" changed_hello.diff) -le 1\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context does not include preceding empty lines">)} 
      {(SQ <"\n"> <"\ttest \"$(first_context_line <changed_hello.diff)\" != \" \"\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context does not include trailing empty lines">)} 
      {(SQ <"\n"> <"\ttest \"$(last_context_line <changed_hello.diff)\" != \" \"\n">)}
    )
    (C {(check_diff)} {(changed_includes)} {(SQ <"changed includes">)})
    (C {(test_expect_success)} {(SQ <" context includes begin">)} 
      {(SQ <"\n"> <"\tgrep \"^ .*Begin.h\" changed_includes.diff\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context includes end">)} 
      {(SQ <"\n"> <"\tgrep \"^ .*End.h\" changed_includes.diff\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context does not include other functions">)} 
      {(SQ <"\n"> <"\ttest $(grep -c \"^[ +-].*Begin\" changed_includes.diff) -le 1\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context does not include trailing empty lines">)} 
      {(SQ <"\n"> <"\ttest \"$(last_context_line <changed_includes.diff)\" != \" \"\n">)}
    )
    (C {(check_diff)} {(appended)} {(SQ <"appended function">)})
    (C {(test_expect_success)} {(SQ <" context includes begin">)} 
      {(SQ <"\n"> <"\tgrep \"^[+].*Begin of first part\" appended.diff\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context includes end">)} 
      {(SQ <"\n"> <"\tgrep \"^[+].*End of first part\" appended.diff\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context does not include other functions">)} 
      {(SQ <"\n"> <"\ttest $(grep -c \"^[ +-].*Begin\" appended.diff) -le 1\n">)}
    )
    (C {(check_diff)} {(extended)} {(SQ <"appended function part">)})
    (C {(test_expect_success)} {(SQ <" context includes begin">)} 
      {(SQ <"\n"> <"\tgrep \"^ .*Begin of first part\" extended.diff\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context includes end">)} 
      {(SQ <"\n"> <"\tgrep \"^[+].*End of second part\" extended.diff\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context does not include other functions">)} 
      {(SQ <"\n"> <"\ttest $(grep -c \"^[ +-].*Begin\" extended.diff) -le 2\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context does not include preceding empty lines">)} 
      {(SQ <"\n"> <"\ttest \"$(first_context_line <extended.diff)\" != \" \"\n">)}
    )
    (C {(check_diff)} {(long_common_tail)} {(SQ <"change with long common tail and no context">)} {(-U0)})
    (C {(test_expect_success)} {(SQ <" context includes begin">)} 
      {(SQ <"\n"> <"\tgrep \"^ .*Begin of first part\" long_common_tail.diff\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context includes end">)} 
      {(SQ <"\n"> <"\tgrep \"^ .*End of second part\" long_common_tail.diff\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context does not include other functions">)} 
      {(SQ <"\n"> <"\ttest $(grep -c \"^[ +-].*Begin\" long_common_tail.diff) -le 2\n">)}
    )
    (C {(test_expect_success)} {(SQ <" context does not include preceding empty lines">)} 
      {(SQ <"\n"> <"\ttest \"$(first_context_line <long_common_tail.diff.diff)\" != \" \"\n">)}
    )
    (C {(check_diff)} {(changed_hello_appended)} {(SQ <"changed function plus appended function">)})
    (C {(test_expect_success)} {(SQ <" context includes begin">)} 
      {
        (SQ <"\n"> <"\tgrep \"^ .*Begin of hello\" changed_hello_appended.diff &&\n"> 
          <"\tgrep \"^[+].*Begin of first part\" changed_hello_appended.diff\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <" context includes end">)} 
      {
        (SQ <"\n"> <"\tgrep \"^ .*End of hello\" changed_hello_appended.diff &&\n"> 
          <"\tgrep \"^[+].*End of first part\" changed_hello_appended.diff\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <" context does not include other functions">)} 
      {(SQ <"\n"> <"\ttest $(grep -c \"^[ +-].*Begin\" changed_hello_appended.diff) -le 2\n">)}
    )
    (C {(check_diff)} {(changed_hello_dummy)} {(SQ <"changed two consecutive functions">)})
    (C {(test_expect_success)} {(SQ <" context includes begin">)} 
      {
        (SQ <"\n"> <"\tgrep \"^ .*Begin of hello\" changed_hello_dummy.diff &&\n"> 
          <"\tgrep \"^ .*Begin of dummy\" changed_hello_dummy.diff\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <" context includes end">)} 
      {
        (SQ <"\n"> <"\tgrep \"^ .*End of hello\" changed_hello_dummy.diff &&\n"> 
          <"\tgrep \"^ .*End of dummy\" changed_hello_dummy.diff\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <" overlapping hunks are merged">)} 
      {(SQ <"\n"> <"\ttest $(grep -c \"^@@\" changed_hello_dummy.diff) -eq 1\n">)}
    )
    (C {(test_done)})
  ]
)