(command.CommandList
  children: [
    (command.Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (lhs_expr.LhsName name:test_description spids:[15])
          op: Equal
          rhs: {(SQ <'Recursive "git fetch" for submodules'>)}
          spids: [15]
        )
      ]
      spids: [15]
    )
    (C {(.)} {(./test-lib.sh)})
    (command.Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (lhs_expr.LhsName name:pwd spids:[26])
          op: Equal
          rhs: 
            {
              (word_part.CommandSubPart
                command_list: (command.CommandList children:[(C {(pwd)})])
                left_token: <Left_CommandSub '$('>
                spids: [27 29]
              )
            }
          spids: [26]
        )
      ]
      spids: [26]
    )
    (command.FuncDef
      name: add_upstream_commit
      body: 
        (command.BraceGroup
          children: [
            (command.AndOr
              ops: [Op_DAmp]
              children: [
                (command.Subshell
                  child: 
                    (command.AndOr
                      ops: [Op_DAmp Op_DAmp Op_DAmp Op_DAmp Op_DAmp Op_DAmp Op_DAmp Op_DAmp Op_DAmp]
                      children: [
                        (C {(cd)} {(submodule)})
                        (command.Assignment
                          keyword: Assign_None
                          pairs: [
                            (assign_pair
                              lhs: (lhs_expr.LhsName name:head1 spids:[49])
                              op: Equal
                              rhs: 
                                {
                                  (word_part.CommandSubPart
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(git)} {(rev-parse)} {(--short)} {(HEAD)})]
                                      )
                                    left_token: <Left_CommandSub '$('>
                                    spids: [50 58]
                                  )
                                }
                              spids: [49]
                            )
                          ]
                          spids: [49]
                        )
                        (command.SimpleCommand
                          words: [{(echo)} {(new)}]
                          redirects: [
                            (redir.Redir
                              op: <Redir_DGreat '>>'>
                              fd: 16777215
                              arg_word: {(subfile)}
                            )
                          ]
                        )
                        (C {(test_tick)})
                        (C {(git)} {(add)} {(subfile)})
                        (C {(git)} {(commit)} {(-m)} {(new)} {(subfile)})
                        (command.Assignment
                          keyword: Assign_None
                          pairs: [
                            (assign_pair
                              lhs: (lhs_expr.LhsName name:head2 spids:[101])
                              op: Equal
                              rhs: 
                                {
                                  (word_part.CommandSubPart
                                    command_list: 
                                      (command.CommandList
                                        children: [(C {(git)} {(rev-parse)} {(--short)} {(HEAD)})]
                                      )
                                    left_token: <Left_CommandSub '$('>
                                    spids: [102 110]
                                  )
                                }
                              spids: [101]
                            )
                          ]
                          spids: [101]
                        )
                        (command.SimpleCommand
                          words: [{(echo)} {(DQ ('Fetching submodule submodule'))}]
                          redirects: [
                            (redir.Redir
                              op: <Redir_Great '>'>
                              fd: 16777215
                              arg_word: {(../expect.err)}
                            )
                          ]
                        )
                        (command.SimpleCommand
                          words: [{(echo)} {(DQ ('From ') ($ VSub_Name '$pwd') (/submodule))}]
                          redirects: [
                            (redir.Redir
                              op: <Redir_DGreat '>>'>
                              fd: 16777215
                              arg_word: {(../expect.err)}
                            )
                          ]
                        )
                        (command.SimpleCommand
                          words: [
                            {(echo)}
                            {
                              (DQ ('   ') ($ VSub_Name '$head1') (..) ($ VSub_Name '$head2') 
                                ('  master     -> origin/master')
                              )
                            }
                          ]
                          redirects: [
                            (redir.Redir
                              op: <Redir_DGreat '>>'>
                              fd: 16777215
                              arg_word: {(../expect.err)}
                            )
                          ]
                        )
                      ]
                    )
                  spids: [39 158]
                )
                (command.Subshell
                  child: 
                    (command.CommandList
                      children: [
                        (command.AndOr
                          ops: [Op_DAmp Op_DAmp Op_DAmp Op_DAmp Op_DAmp Op_DAmp Op_DAmp]
                          children: [
                            (C {(cd)} {(deepsubmodule)})
                            (command.Assignment
                              keyword: Assign_None
                              pairs: [
                                (assign_pair
                                  lhs: (lhs_expr.LhsName name:head1 spids:[173])
                                  op: Equal
                                  rhs: 
                                    {
                                      (word_part.CommandSubPart
                                        command_list: 
                                          (command.CommandList
                                            children: [(C {(git)} {(rev-parse)} {(--short)} {(HEAD)})]
                                          )
                                        left_token: <Left_CommandSub '$('>
                                        spids: [174 182]
                                      )
                                    }
                                  spids: [173]
                                )
                              ]
                              spids: [173]
                            )
                            (command.SimpleCommand
                              words: [{(echo)} {(new)}]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_DGreat '>>'>
                                  fd: 16777215
                                  arg_word: {(deepsubfile)}
                                )
                              ]
                            )
                            (C {(test_tick)})
                            (C {(git)} {(add)} {(deepsubfile)})
                            (C {(git)} {(commit)} {(-m)} {(new)} {(deepsubfile)})
                            (command.Assignment
                              keyword: Assign_None
                              pairs: [
                                (assign_pair
                                  lhs: (lhs_expr.LhsName name:head2 spids:[225])
                                  op: Equal
                                  rhs: 
                                    {
                                      (word_part.CommandSubPart
                                        command_list: 
                                          (command.CommandList
                                            children: [(C {(git)} {(rev-parse)} {(--short)} {(HEAD)})]
                                          )
                                        left_token: <Left_CommandSub '$('>
                                        spids: [226 234]
                                      )
                                    }
                                  spids: [225]
                                )
                              ]
                              spids: [225]
                            )
                            (command.SimpleCommand
                              words: [
                                {(echo)}
                                {(DQ ('Fetching submodule submodule/subdir/deepsubmodule'))}
                              ]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_DGreat '>>'>
                                  fd: 16777215
                                  arg_word: {(../expect.err)}
                                )
                              ]
                            )
                          ]
                        )
                        (command.AndOr
                          ops: [Op_DAmp]
                          children: [
                            (command.SimpleCommand
                              words: [{(echo)} {(DQ ('From ') ($ VSub_Name '$pwd') (/deepsubmodule))}]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_DGreat '>>'>
                                  fd: 16777215
                                  arg_word: {(../expect.err)}
                                )
                              ]
                            )
                            (command.SimpleCommand
                              words: [
                                {(echo)}
                                {
                                  (DQ ('   ') ($ VSub_Name '$head1') (..) ($ VSub_Name '$head2') 
                                    ('  master     -> origin/master')
                                  )
                                }
                              ]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_DGreat '>>'>
                                  fd: 16777215
                                  arg_word: {(../expect.err)}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                  spids: [163 280]
                )
              ]
            )
          ]
          spids: [36]
        )
      spids: [32 35]
    )
    (C {(test_expect_success)} {(setup)} 
      {
        (SQ <'\n'> <'\tmkdir deepsubmodule &&\n'> <'\t(\n'> <'\t\tcd deepsubmodule &&\n'> 
          <'\t\tgit init &&\n'> <'\t\techo deepsubcontent > deepsubfile &&\n'> <'\t\tgit add deepsubfile &&\n'> 
          <'\t\tgit commit -m new deepsubfile\n'> <'\t) &&\n'> <'\tmkdir submodule &&\n'> <'\t(\n'> <'\t\tcd submodule &&\n'> <'\t\tgit init &&\n'> 
          <'\t\techo subcontent > subfile &&\n'> <'\t\tgit add subfile &&\n'> <'\t\tgit submodule add "$pwd/deepsubmodule" subdir/deepsubmodule &&\n'> 
          <'\t\tgit commit -a -m new\n'> <'\t) &&\n'> <'\tgit submodule add "$pwd/submodule" submodule &&\n'> <'\tgit commit -am initial &&\n'> 
          <'\tgit clone . downstream &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> <'\t\tgit submodule update --init --recursive\n'> <'\t)\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('fetch --recurse-submodules recurses into submodules'))} 
      {
        (SQ <'\n'> <'\tadd_upstream_commit &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit fetch --recurse-submodules >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\ttest_must_be_empty actual.out &&\n'> <'\ttest_i18ncmp expect.err actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('fetch --recurse-submodules -j2 has the same output behaviour'))} 
      {
        (SQ <'\n'> <'\tadd_upstream_commit &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <
'\t\tGIT_TRACE=$(pwd)/../trace.out git fetch --recurse-submodules -j2 2>../actual.err\n'
          > <'\t) &&\n'> <'\ttest_must_be_empty actual.out &&\n'> <'\ttest_i18ncmp expect.err actual.err &&\n'> 
          <'\tgrep "2 tasks" trace.out\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('fetch alone only fetches superproject'))} 
      {
        (SQ <'\n'> <'\tadd_upstream_commit &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit fetch >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\t! test -s actual.out &&\n'> <'\t! test -s actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('fetch --no-recurse-submodules only fetches superproject'))} 
      {
        (SQ <'\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit fetch --no-recurse-submodules >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\t! test -s actual.out &&\n'> <'\t! test -s actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} 
      {(DQ ('using fetchRecurseSubmodules=true in .gitmodules recurses into submodules'))} 
      {
        (SQ <'\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit config -f .gitmodules submodule.submodule.fetchRecurseSubmodules true &&\n'> <'\t\tgit fetch >../actual.out 2>../actual.err\n'> <'\t) &&\n'> 
          <'\ttest_must_be_empty actual.out &&\n'> <'\ttest_i18ncmp expect.err actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('--no-recurse-submodules overrides .gitmodules config'))} 
      {
        (SQ <'\n'> <'\tadd_upstream_commit &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit fetch --no-recurse-submodules >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\t! test -s actual.out &&\n'> <'\t! test -s actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} 
      {(DQ ('using fetchRecurseSubmodules=false in .git/config overrides setting in .gitmodules'))} 
      {
        (SQ <'\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit config submodule.submodule.fetchRecurseSubmodules false &&\n'> <'\t\tgit fetch >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\t! test -s actual.out &&\n'> 
          <'\t! test -s actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} 
      {(DQ ('--recurse-submodules overrides fetchRecurseSubmodules setting from .git/config'))} 
      {
        (SQ <'\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit fetch --recurse-submodules >../actual.out 2>../actual.err &&\n'> <'\t\tgit config --unset -f .gitmodules submodule.submodule.fetchRecurseSubmodules &&\n'> 
          <'\t\tgit config --unset submodule.submodule.fetchRecurseSubmodules\n'> <'\t) &&\n'> <'\ttest_must_be_empty actual.out &&\n'> <'\ttest_i18ncmp expect.err actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('--quiet propagates to submodules'))} 
      {
        (SQ <'\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit fetch --recurse-submodules --quiet >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\t! test -s actual.out &&\n'> <'\t! test -s actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('--quiet propagates to parallel submodules'))} 
      {
        (SQ <'\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit fetch --recurse-submodules -j 2 --quiet  >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\t! test -s actual.out &&\n'> <'\t! test -s actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('--dry-run propagates to submodules'))} 
      {
        (SQ <'\n'> <'\tadd_upstream_commit &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit fetch --recurse-submodules --dry-run >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\ttest_must_be_empty actual.out &&\n'> <'\ttest_i18ncmp expect.err actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('Without --dry-run propagates to submodules'))} 
      {
        (SQ <'\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit fetch --recurse-submodules >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\ttest_must_be_empty actual.out &&\n'> <'\ttest_i18ncmp expect.err actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('recurseSubmodules=true propagates into submodules'))} 
      {
        (SQ <'\n'> <'\tadd_upstream_commit &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit config fetch.recurseSubmodules true\n'> <'\t\tgit fetch >../actual.out 2>../actual.err\n'> <'\t) &&\n'> 
          <'\ttest_must_be_empty actual.out &&\n'> <'\ttest_i18ncmp expect.err actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('--recurse-submodules overrides config in submodule'))} 
      {
        (SQ <'\n'> <'\tadd_upstream_commit &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> <'\t\t(\n'> 
          <'\t\t\tcd submodule &&\n'> <'\t\t\tgit config fetch.recurseSubmodules false\n'> <'\t\t) &&\n'> 
          <'\t\tgit fetch --recurse-submodules >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\ttest_must_be_empty actual.out &&\n'> <'\ttest_i18ncmp expect.err actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('--no-recurse-submodules overrides config setting'))} 
      {
        (SQ <'\n'> <'\tadd_upstream_commit &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit config fetch.recurseSubmodules true\n'> <'\t\tgit fetch --no-recurse-submodules >../actual.out 2>../actual.err\n'> <'\t) &&\n'> 
          <'\t! test -s actual.out &&\n'> <'\t! test -s actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} 
      {(DQ ("Recursion doesn't happen when no new commits are fetched in the superproject"))} 
      {
        (SQ <'\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> <'\t\t(\n'> <'\t\t\tcd submodule &&\n'> 
          <'\t\t\tgit config --unset fetch.recurseSubmodules\n'> <'\t\t) &&\n'> <'\t\tgit config --unset fetch.recurseSubmodules\n'> 
          <'\t\tgit fetch >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\t! test -s actual.out &&\n'> <'\t! test -s actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('Recursion stops when no new submodule commits are fetched'))} 
      {
        (SQ <'\n'> <'\thead1=$(git rev-parse --short HEAD) &&\n'> <'\tgit add submodule &&\n'> 
          <'\tgit commit -m "new submodule" &&\n'> <'\thead2=$(git rev-parse --short HEAD) &&\n'> <'\techo "From $pwd/." > expect.err.sub &&\n'> 
          <'\techo "   $head1..$head2  master     -> origin/master" >>expect.err.sub &&\n'> <'\thead -3 expect.err >> expect.err.sub &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit fetch >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\ttest_i18ncmp expect.err.sub actual.err &&\n'> <'\ttest_must_be_empty actual.out\n'>
        )
      }
    )
    (C {(test_expect_success)} 
      {(DQ ("Recursion doesn't happen when new superproject commits don't change any submodules"))} 
      {
        (SQ <'\n'> <'\tadd_upstream_commit &&\n'> <'\thead1=$(git rev-parse --short HEAD) &&\n'> 
          <'\techo a > file &&\n'> <'\tgit add file &&\n'> <'\tgit commit -m "new file" &&\n'> 
          <'\thead2=$(git rev-parse --short HEAD) &&\n'> <'\techo "From $pwd/." > expect.err.file &&\n'> 
          <'\techo "   $head1..$head2  master     -> origin/master" >> expect.err.file &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> <'\t\tgit fetch >../actual.out 2>../actual.err\n'> <'\t) &&\n'> 
          <'\t! test -s actual.out &&\n'> <'\ttest_i18ncmp expect.err.file actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('Recursion picks up config in submodule'))} 
      {
        (SQ <'\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> <'\t\tgit fetch --recurse-submodules &&\n'> 
          <'\t\t(\n'> <'\t\t\tcd submodule &&\n'> <'\t\t\tgit config fetch.recurseSubmodules true\n'> <'\t\t)\n'> <'\t) &&\n'> 
          <'\tadd_upstream_commit &&\n'> <'\thead1=$(git rev-parse --short HEAD) &&\n'> <'\tgit add submodule &&\n'> 
          <'\tgit commit -m "new submodule" &&\n'> <'\thead2=$(git rev-parse --short HEAD) &&\n'> <'\techo "From $pwd/." > expect.err.sub &&\n'> 
          <'\techo "   $head1..$head2  master     -> origin/master" >> expect.err.sub &&\n'> <'\tcat expect.err >> expect.err.sub &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit fetch >../actual.out 2>../actual.err &&\n'> <'\t\t(\n'> <'\t\t\tcd submodule &&\n'> <'\t\t\tgit config --unset fetch.recurseSubmodules\n'> 
          <'\t\t)\n'> <'\t) &&\n'> <'\ttest_i18ncmp expect.err.sub actual.err &&\n'> <'\ttest_must_be_empty actual.out\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ('Recursion picks up all submodules when necessary'))} 
      {
        (SQ <'\n'> <'\tadd_upstream_commit &&\n'> <'\t(\n'> <'\t\tcd submodule &&\n'> <'\t\t(\n'> 
          <'\t\t\tcd subdir/deepsubmodule &&\n'> <'\t\t\tgit fetch &&\n'> <'\t\t\tgit checkout -q FETCH_HEAD\n'> <'\t\t) &&\n'> 
          <'\t\thead1=$(git rev-parse --short HEAD^) &&\n'> <'\t\tgit add subdir/deepsubmodule &&\n'> <'\t\tgit commit -m "new deepsubmodule"\n'> 
          <'\t\thead2=$(git rev-parse --short HEAD) &&\n'> <'\t\techo "Fetching submodule submodule" > ../expect.err.sub &&\n'> 
          <'\t\techo "From $pwd/submodule" >> ../expect.err.sub &&\n'> <'\t\techo "   $head1..$head2  master     -> origin/master" >> ../expect.err.sub\n'> <'\t) &&\n'> 
          <'\thead1=$(git rev-parse --short HEAD) &&\n'> <'\tgit add submodule &&\n'> <'\tgit commit -m "new submodule" &&\n'> 
          <'\thead2=$(git rev-parse --short HEAD) &&\n'> <'\techo "From $pwd/." > expect.err.2 &&\n'> 
          <'\techo "   $head1..$head2  master     -> origin/master" >> expect.err.2 &&\n'> <'\tcat expect.err.sub >> expect.err.2 &&\n'> <'\ttail -3 expect.err >> expect.err.2 &&\n'> <'\t(\n'> 
          <'\t\tcd downstream &&\n'> <'\t\tgit fetch >../actual.out 2>../actual.err\n'> <'\t) &&\n'> 
          <'\ttest_i18ncmp expect.err.2 actual.err &&\n'> <'\ttest_must_be_empty actual.out\n'>
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (DQ 
          (
"'--recurse-submodules=on-demand' doesn't recurse when no new commits are fetched in the superproject (and ignores config)"
          )
        )
      } 
      {
        (SQ <'\n'> <'\tadd_upstream_commit &&\n'> <'\t(\n'> <'\t\tcd submodule &&\n'> <'\t\t(\n'> 
          <'\t\t\tcd subdir/deepsubmodule &&\n'> <'\t\t\tgit fetch &&\n'> <'\t\t\tgit checkout -q FETCH_HEAD\n'> <'\t\t) &&\n'> 
          <'\t\thead1=$(git rev-parse --short HEAD^) &&\n'> <'\t\tgit add subdir/deepsubmodule &&\n'> <'\t\tgit commit -m "new deepsubmodule" &&\n'> 
          <'\t\thead2=$(git rev-parse --short HEAD) &&\n'> <'\t\techo Fetching submodule submodule > ../expect.err.sub &&\n'> 
          <'\t\techo "From $pwd/submodule" >> ../expect.err.sub &&\n'> <'\t\techo "   $head1..$head2  master     -> origin/master" >> ../expect.err.sub\n'> <'\t) &&\n'> 
          <'\t(\n'> <'\t\tcd downstream &&\n'> <'\t\tgit config fetch.recurseSubmodules true &&\n'> 
          <'\t\tgit fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err &&\n'> <'\t\tgit config --unset fetch.recurseSubmodules\n'> <'\t) &&\n'> <'\t! test -s actual.out &&\n'> 
          <'\t! test -s actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} 
      {(DQ ("'--recurse-submodules=on-demand' recurses as deep as necessary (and ignores config)"))} 
      {
        (SQ <'\n'> <'\thead1=$(git rev-parse --short HEAD) &&\n'> <'\tgit add submodule &&\n'> 
          <'\tgit commit -m "new submodule" &&\n'> <'\thead2=$(git rev-parse --short HEAD) &&\n'> <'\ttail -3 expect.err > expect.err.deepsub &&\n'> 
          <'\techo "From $pwd/." > expect.err &&\n'> <'\techo "   $head1..$head2  master     -> origin/master" >>expect.err &&\n'> 
          <'\tcat expect.err.sub >> expect.err &&\n'> <'\tcat expect.err.deepsub >> expect.err &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit config fetch.recurseSubmodules false &&\n'> <'\t\t(\n'> <'\t\t\tcd submodule &&\n'> 
          <'\t\t\tgit config -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive false\n'> <'\t\t) &&\n'> <'\t\tgit fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err &&\n'> 
          <'\t\tgit config --unset fetch.recurseSubmodules\n'> <'\t\t(\n'> <'\t\t\tcd submodule &&\n'> 
          <
'\t\t\tgit config --unset -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive\n'
          > <'\t\t)\n'> <'\t) &&\n'> <'\ttest_must_be_empty actual.out &&\n'> 
          <'\ttest_i18ncmp expect.err actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (DQ 
          (
"'--recurse-submodules=on-demand' stops when no new submodule commits are found in the superproject (and ignores config)"
          )
        )
      } 
      {
        (SQ <'\n'> <'\tadd_upstream_commit &&\n'> <'\thead1=$(git rev-parse --short HEAD) &&\n'> 
          <'\techo a >> file &&\n'> <'\tgit add file &&\n'> <'\tgit commit -m "new file" &&\n'> 
          <'\thead2=$(git rev-parse --short HEAD) &&\n'> <'\techo "From $pwd/." > expect.err.file &&\n'> 
          <'\techo "   $head1..$head2  master     -> origin/master" >> expect.err.file &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err\n'> <'\t) &&\n'> <'\t! test -s actual.out &&\n'> <'\ttest_i18ncmp expect.err.file actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(DQ ("'fetch.recurseSubmodules=on-demand' overrides global config"))} 
      {
        (SQ <'\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> <'\t\tgit fetch --recurse-submodules\n'> 
          <'\t) &&\n'> <'\tadd_upstream_commit &&\n'> <'\tgit config --global fetch.recurseSubmodules false &&\n'> 
          <'\thead1=$(git rev-parse --short HEAD) &&\n'> <'\tgit add submodule &&\n'> <'\tgit commit -m "new submodule" &&\n'> 
          <'\thead2=$(git rev-parse --short HEAD) &&\n'> <'\techo "From $pwd/." > expect.err.2 &&\n'> 
          <'\techo "   $head1..$head2  master     -> origin/master" >>expect.err.2 &&\n'> <'\thead -3 expect.err >> expect.err.2 &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit config fetch.recurseSubmodules on-demand &&\n'> <'\t\tgit fetch >../actual.out 2>../actual.err\n'> <'\t) &&\n'> 
          <'\tgit config --global --unset fetch.recurseSubmodules &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> <'\t\tgit config --unset fetch.recurseSubmodules\n'> <'\t) &&\n'> 
          <'\ttest_must_be_empty actual.out &&\n'> <'\ttest_i18ncmp expect.err.2 actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} 
      {(DQ ("'submodule.<sub>.fetchRecurseSubmodules=on-demand' overrides fetch.recurseSubmodules"))} 
      {
        (SQ <'\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> <'\t\tgit fetch --recurse-submodules\n'> 
          <'\t) &&\n'> <'\tadd_upstream_commit &&\n'> <'\tgit config fetch.recurseSubmodules false &&\n'> 
          <'\thead1=$(git rev-parse --short HEAD) &&\n'> <'\tgit add submodule &&\n'> <'\tgit commit -m "new submodule" &&\n'> 
          <'\thead2=$(git rev-parse --short HEAD) &&\n'> <'\techo "From $pwd/." > expect.err.2 &&\n'> 
          <'\techo "   $head1..$head2  master     -> origin/master" >>expect.err.2 &&\n'> <'\thead -3 expect.err >> expect.err.2 &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit config submodule.submodule.fetchRecurseSubmodules on-demand &&\n'> <'\t\tgit fetch >../actual.out 2>../actual.err\n'> <'\t) &&\n'> 
          <'\tgit config --unset fetch.recurseSubmodules &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> 
          <'\t\tgit config --unset submodule.submodule.fetchRecurseSubmodules\n'> <'\t) &&\n'> <'\ttest_must_be_empty actual.out &&\n'> <'\ttest_i18ncmp expect.err.2 actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} 
      {(DQ ("don't fetch submodule when newly recorded commits are already present"))} 
      {
        (SQ <'\n'> <'\t(\n'> <'\t\tcd submodule &&\n'> <'\t\tgit checkout -q HEAD^^\n'> <'\t) &&\n'> 
          <'\thead1=$(git rev-parse --short HEAD) &&\n'> <'\tgit add submodule &&\n'> <'\tgit commit -m "submodule rewound" &&\n'> 
          <'\thead2=$(git rev-parse --short HEAD) &&\n'> <'\techo "From $pwd/." > expect.err &&\n'> 
          <'\techo "   $head1..$head2  master     -> origin/master" >> expect.err &&\n'> <'\t(\n'> <'\t\tcd downstream &&\n'> <'\t\tgit fetch >../actual.out 2>../actual.err\n'> <'\t) &&\n'> 
          <'\t! test -s actual.out &&\n'> <'\ttest_i18ncmp expect.err actual.err\n'>
        )
      }
    )
    (C {(test_expect_success)} {(SQ <'fetching submodules respects parallel settings'>)} 
      {
        (SQ <'\n'> <'\tgit config fetch.recurseSubmodules true &&\n'> <'\t(\n'> 
          <'\t\tcd downstream &&\n'> <'\t\tGIT_TRACE=$(pwd)/trace.out git fetch --jobs 7 &&\n'> <'\t\tgrep "7 tasks" trace.out &&\n'> 
          <'\t\tgit config submodule.fetchJobs 8 &&\n'> <'\t\tGIT_TRACE=$(pwd)/trace.out git fetch &&\n'> <'\t\tgrep "8 tasks" trace.out &&\n'> 
          <'\t\tGIT_TRACE=$(pwd)/trace.out git fetch --jobs 9 &&\n'> <'\t\tgrep "9 tasks" trace.out\n'> <'\t)\n'>
        )
      }
    )
    (C {(test_expect_success)} {(SQ <'fetching submodule into a broken repository'>)} 
      {
        (SQ <'\n'> <'\t# Prepare src and src/sub nested in it\n'> <'\tgit init src &&\n'> <'\t(\n'> 
          <'\t\tcd src &&\n'> <'\t\tgit init sub &&\n'> <'\t\tgit -C sub commit --allow-empty -m "initial in sub" &&\n'> 
          <'\t\tgit submodule add -- ./sub sub &&\n'> <'\t\tgit commit -m "initial in top"\n'> <'\t) &&\n'> <'\n'> <'\t# Clone the old-fashoned way\n'> 
          <'\tgit clone src dst &&\n'> <'\tgit -C dst clone ../src/sub sub &&\n'> <'\n'> 
          <'\t# Make sure that old-fashoned layout is still supported\n'> <'\tgit -C dst status &&\n'> <'\n'> <'\t# "diff" would find no change\n'> 
          <'\tgit -C dst diff --exit-code &&\n'> <'\n'> <'\t# Recursive-fetch works fine\n'> <'\tgit -C dst fetch --recurse-submodules &&\n'> <'\n'> 
          <'\t# Break the receiving submodule\n'> <'\trm -f dst/sub/.git/HEAD &&\n'> <'\n'> 
          <'\t# NOTE: without the fix the following tests will recurse forever!\n'> <'\t# They should terminate with an error.\n'> <'\n'> <'\ttest_must_fail git -C dst status &&\n'> 
          <'\ttest_must_fail git -C dst diff &&\n'> <'\ttest_must_fail git -C dst fetch --recurse-submodules\n'>
        )
      }
    )
    (C {(test_done)})
  ]
)