(CommandList
  children: [
    (Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (LhsName name:test_description)
          op: Equal
          rhs: {(SQ <"add -i basic tests">)}
          spids: [4]
        )
      ]
      spids: [4]
    )
    (C {(.)} {(./test-lib.sh)})
    (If
      arms: [
        (if_arm
          cond: [(Pipeline children:[(C {(test_have_prereq)} {(PERL)})] negated:True)]
          action: [
            (Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (LhsName name:skip_all)
                  op: Equal
                  rhs: {(SQ <"skipping add -i tests, perl not available">)}
                  spids: [25]
                )
              ]
              spids: [25]
            )
            (C {(test_done)})
          ]
          spids: [-1 22]
        )
      ]
      spids: [-1 33]
    )
    (C {(test_expect_success)} {(SQ <"setup (initial)">)} 
      {
        (SQ <"\n"> <"\techo content >file &&\n"> <"\tgit add file &&\n"> <"\techo more >>file &&\n"> 
          <"\techo lines >>file\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"status works (initial)">)} 
      {
        (SQ <"\n"> <"\tgit add -i </dev/null >output &&\n"> <"\tgrep \"+1/-0 *+2/-0 file\" output\n">)
      }
    )
    (C {(test_expect_success)} {(SQ <"setup expected">)} 
      {
        (SQ <"\n"> <"cat >expected <<EOF\n"> <"new file mode 100644\n"> <"index 0000000..d95f3ad\n"> 
          <"--- /dev/null\n"> <"+++ b/file\n"> <"@@ -0,0 +1 @@\n"> <"+content\n"> <"EOF\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"diff works (initial)">)} 
      {
        (SQ <"\n"> <"\t(echo d; echo 1) | git add -i >output &&\n"> 
          <"\tsed -ne \"/new file/,/content/p\" <output >diff &&\n"> <"\ttest_cmp expected diff\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"revert works (initial)">)} 
      {
        (SQ <"\n"> <"\tgit add file &&\n"> <"\t(echo r; echo 1) | git add -i &&\n"> 
          <"\tgit ls-files >output &&\n"> <"\t! grep . output\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup (commit)">)} 
      {
        (SQ <"\n"> <"\techo baseline >file &&\n"> <"\tgit add file &&\n"> 
          <"\tgit commit -m commit &&\n"> <"\techo content >>file &&\n"> <"\tgit add file &&\n"> <"\techo more >>file &&\n"> 
          <"\techo lines >>file\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"status works (commit)">)} 
      {
        (SQ <"\n"> <"\tgit add -i </dev/null >output &&\n"> <"\tgrep \"+1/-0 *+2/-0 file\" output\n">)
      }
    )
    (C {(test_expect_success)} {(SQ <"setup expected">)} 
      {
        (SQ <"\n"> <"cat >expected <<EOF\n"> <"index 180b47c..b6f2c08 100644\n"> <"--- a/file\n"> 
          <"+++ b/file\n"> <"@@ -1 +1,2 @@\n"> <" baseline\n"> <"+content\n"> <"EOF\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"diff works (commit)">)} 
      {
        (SQ <"\n"> <"\t(echo d; echo 1) | git add -i >output &&\n"> 
          <"\tsed -ne \"/^index/,/content/p\" <output >diff &&\n"> <"\ttest_cmp expected diff\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"revert works (commit)">)} 
      {
        (SQ <"\n"> <"\tgit add file &&\n"> <"\t(echo r; echo 1) | git add -i &&\n"> 
          <"\tgit add -i </dev/null >output &&\n"> <"\tgrep \"unchanged *+3/-0 file\" output\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup expected">)} 
      {(SQ <"\n"> <"cat >expected <<EOF\n"> <"EOF\n">)}
    )
    (C {(test_expect_success)} {(SQ <"setup fake editor">)} 
      {
        (SQ <"\n"> <"\t>fake_editor.sh &&\n"> <"\tchmod a+x fake_editor.sh &&\n"> 
          <"\ttest_set_editor \"$(pwd)/fake_editor.sh\"\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"dummy edit works">)} 
      {
        (SQ <"\n"> <"\t(echo e; echo a) | git add -p &&\n"> <"\tgit diff > diff &&\n"> 
          <"\ttest_cmp expected diff\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup patch">)} 
      {
        (SQ <"\n"> <"cat >patch <<EOF\n"> <"@@ -1,1 +1,4 @@\n"> <" this\n"> <"+patch\n"> <"-does not\n"> 
          <" apply\n"> <"EOF\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup fake editor">)} 
      {
        (SQ <"\n"> <"\techo \"#!$SHELL_PATH\" >fake_editor.sh &&\n"> 
          <"\tcat >>fake_editor.sh <<\\EOF &&\n"> <"mv -f \"$1\" oldpatch &&\n"> <"mv -f patch \"$1\"\n"> <"EOF\n"> <"\tchmod a+x fake_editor.sh &&\n"> 
          <"\ttest_set_editor \"$(pwd)/fake_editor.sh\"\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"bad edit rejected">)} 
      {
        (SQ <"\n"> <"\tgit reset &&\n"> <"\t(echo e; echo n; echo d) | git add -p >output &&\n"> 
          <"\tgrep \"hunk does not apply\" output\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup patch">)} 
      {(SQ <"\n"> <"cat >patch <<EOF\n"> <"this patch\n"> <"is garbage\n"> <"EOF\n">)}
    )
    (C {(test_expect_success)} {(SQ <"garbage edit rejected">)} 
      {
        (SQ <"\n"> <"\tgit reset &&\n"> <"\t(echo e; echo n; echo d) | git add -p >output &&\n"> 
          <"\tgrep \"hunk does not apply\" output\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup patch">)} 
      {
        (SQ <"\n"> <"cat >patch <<EOF\n"> <"@@ -1,0 +1,0 @@\n"> <" baseline\n"> <"+content\n"> 
          <"+newcontent\n"> <"+lines\n"> <"EOF\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup expected">)} 
      {
        (SQ <"\n"> <"cat >expected <<EOF\n"> <"diff --git a/file b/file\n"> 
          <"index b5dd6c9..f910ae9 100644\n"> <"--- a/file\n"> <"+++ b/file\n"> <"@@ -1,4 +1,4 @@\n"> <" baseline\n"> <" content\n"> <"-newcontent\n"> 
          <"+more\n"> <" lines\n"> <"EOF\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"real edit works">)} 
      {
        (SQ <"\n"> <"\t(echo e; echo n; echo d) | git add -p &&\n"> <"\tgit diff >output &&\n"> 
          <"\ttest_cmp expected output\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"skip files similarly as commit -a">)} 
      {
        (SQ <"\n"> <"\tgit reset &&\n"> <"\techo file >.gitignore &&\n"> <"\techo changed >file &&\n"> 
          <"\techo y | git add -p file &&\n"> <"\tgit diff >output &&\n"> <"\tgit reset &&\n"> <"\tgit commit -am commit &&\n"> 
          <"\tgit diff >expected &&\n"> <"\ttest_cmp expected output &&\n"> <"\tgit reset --hard HEAD^\n">
        )
      }
    )
    (C {(rm)} {(-f)} {(.gitignore)})
    (C {(test_expect_success)} {(FILEMODE)} {(SQ <"patch does not affect mode">)} 
      {
        (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\techo content >>file &&\n"> <"\tchmod +x file &&\n"> 
          <"\tprintf \"n\\\\ny\\\\n\" | git add -p &&\n"> <"\tgit show :file | grep content &&\n"> <"\tgit diff file | grep \"new mode\"\n">
        )
      }
    )
    (C {(test_expect_success)} {(FILEMODE)} {(SQ <"stage mode but not hunk">)} 
      {
        (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\techo content >>file &&\n"> <"\tchmod +x file &&\n"> 
          <"\tprintf \"y\\\\nn\\\\n\" | git add -p &&\n"> <"\tgit diff --cached file | grep \"new mode\" &&\n"> 
          <"\tgit diff          file | grep \"+content\"\n">
        )
      }
    )
    (C {(test_expect_success)} {(FILEMODE)} {(SQ <"stage mode and hunk">)} 
      {
        (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\techo content >>file &&\n"> <"\tchmod +x file &&\n"> 
          <"\tprintf \"y\\\\ny\\\\n\" | git add -p &&\n"> <"\tgit diff --cached file | grep \"new mode\" &&\n"> 
          <"\tgit diff --cached file | grep \"+content\" &&\n"> <"\ttest -z \"$(git diff file)\"\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup again">)} 
      {
        (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\ttest_chmod +x file &&\n"> <"\techo content >>file\n">)
      }
    )
    (C {(test_expect_success)} {(SQ <"setup patch">)} 
      {
        (SQ <"\n"> <"cat >patch <<EOF\n"> <"index 180b47c..b6f2c08 100644\n"> <"--- a/file\n"> 
          <"+++ b/file\n"> <"@@ -1,2 +1,4 @@\n"> <"+firstline\n"> <" baseline\n"> <" content\n"> <"+lastline\n"> <"EOF\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup expected">)} 
      {
        (SQ <"\n"> <"cat >expected <<EOF\n"> <"diff --git a/file b/file\n"> 
          <"index b6f2c08..61b9053 100755\n"> <"--- a/file\n"> <"+++ b/file\n"> <"@@ -1,2 +1,4 @@\n"> <"+firstline\n"> <" baseline\n"> <" content\n"> 
          <"+lastline\n"> <"EOF\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"add first line works">)} 
      {
        (SQ <"\n"> <"\tgit commit -am \"clear local changes\" &&\n"> <"\tgit apply patch &&\n"> 
          <"\t(echo s; echo y; echo y) | git add -p file &&\n"> <"\tgit diff --cached > diff &&\n"> <"\ttest_cmp expected diff\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup expected">)} 
      {
        (SQ <"\n"> <"cat >expected <<EOF\n"> <"diff --git a/non-empty b/non-empty\n"> 
          <"deleted file mode 100644\n"> <"index d95f3ad..0000000\n"> <"--- a/non-empty\n"> <"+++ /dev/null\n"> <"@@ -1 +0,0 @@\n"> <"-content\n"> 
          <"EOF\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"deleting a non-empty file">)} 
      {
        (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\techo content >non-empty &&\n"> 
          <"\tgit add non-empty &&\n"> <"\tgit commit -m non-empty &&\n"> <"\trm non-empty &&\n"> <"\techo y | git add -p non-empty &&\n"> 
          <"\tgit diff --cached >diff &&\n"> <"\ttest_cmp expected diff\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup expected">)} 
      {
        (SQ <"\n"> <"cat >expected <<EOF\n"> <"diff --git a/empty b/empty\n"> 
          <"deleted file mode 100644\n"> <"index e69de29..0000000\n"> <"EOF\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"deleting an empty file">)} 
      {
        (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\t> empty &&\n"> <"\tgit add empty &&\n"> 
          <"\tgit commit -m empty &&\n"> <"\trm empty &&\n"> <"\techo y | git add -p empty &&\n"> <"\tgit diff --cached >diff &&\n"> 
          <"\ttest_cmp expected diff\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"split hunk setup">)} 
      {
        (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\tfor i in 10 20 30 40 50 60\n"> <"\tdo\n"> 
          <"\t\techo $i\n"> <"\tdone >test &&\n"> <"\tgit add test &&\n"> <"\ttest_tick &&\n"> <"\tgit commit -m test &&\n"> <"\n"> 
          <"\tfor i in 10 15 20 21 22 23 24 30 40 50 60\n"> <"\tdo\n"> <"\t\techo $i\n"> <"\tdone >test\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"split hunk \"add -p (edit)\"">)} 
      {
        (SQ <"\n"> <"\t# Split, say Edit and do nothing.  Then:\n"> <"\t#\n"> 
          <"\t# 1. Broken version results in a patch that does not apply and\n"> <"\t# only takes [y/n] (edit again) so the first q is discarded\n"> 
          <"\t# and then n attempts to discard the edit. Repeat q enough\n"> <"\t# times to get out.\n"> <"\t#\n"> 
          <"\t# 2. Correct version applies the (not)edited version, and asks\n"> <"\t#    about the next hunk, against which we say q and program\n"> <"\t#    exits.\n"> 
          <"\tprintf \"%s\\n\" s e     q n q q |\n"> <"\tEDITOR=: git add -p &&\n"> <"\tgit diff >actual &&\n"> <"\t! grep \"^+15\" actual\n">
        )
      }
    )
    (C {(test_expect_failure)} {(SQ <"split hunk \"add -p (no, yes, edit)\"">)} 
      {
        (SQ <"\n"> <"\tcat >test <<-\\EOF &&\n"> <"\t5\n"> <"\t10\n"> <"\t20\n"> <"\t21\n"> <"\t30\n"> 
          <"\t31\n"> <"\t40\n"> <"\t50\n"> <"\t60\n"> <"\tEOF\n"> <"\tgit reset &&\n"> 
          <"\t# test sequence is s(plit), n(o), y(es), e(dit)\n"> <"\t# q n q q is there to make sure we exit at the end.\n"> 
          <"\tprintf \"%s\\n\" s n y e   q n q q |\n"> <"\tEDITOR=: git add -p 2>error &&\n"> <"\ttest_must_be_empty error &&\n"> <"\tgit diff >actual &&\n"> 
          <"\t! grep \"^+31\" actual\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"patch mode ignores unmerged entries">)} 
      {
        (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\ttest_commit conflict &&\n"> 
          <"\ttest_commit non-conflict &&\n"> <"\tgit checkout -b side &&\n"> <"\ttest_commit side conflict.t &&\n"> <"\tgit checkout master &&\n"> 
          <"\ttest_commit master conflict.t &&\n"> <"\ttest_must_fail git merge side &&\n"> <"\techo changed >non-conflict.t &&\n"> 
          <"\techo y | git add -p >output &&\n"> <"\t! grep a/conflict.t output &&\n"> <"\tcat >expected <<-\\EOF &&\n"> 
          <"\t* Unmerged path conflict.t\n"> <"\tdiff --git a/non-conflict.t b/non-conflict.t\n"> <"\tindex f766221..5ea2ed4 100644\n"> 
          <"\t--- a/non-conflict.t\n"> <"\t+++ b/non-conflict.t\n"> <"\t@@ -1 +1 @@\n"> <"\t-non-conflict\n"> <"\t+changed\n"> <"\tEOF\n"> 
          <"\tgit diff --cached >diff &&\n"> <"\ttest_cmp expected diff\n">
        )
      }
    )
    (C {(test_done)})
  ]
)