(command.CommandList
  children: [
    (command.Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (lhs_expr.LhsName name:test_description)
          op: Equal
          rhs: {(SQ <'Recursive "git fetch" for submodules'>)}
        )
      ]
    )
    (C {(.)} {(./test-lib.sh)})
    (command.Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (lhs_expr.LhsName name:pwd)
          op: Equal
          rhs: 
            {
              (word_part.CommandSubPart
                command_list: (command.CommandList children:[(C {(pwd)})])
                left_token: <Left_CommandSub '$('>
              )
            }
        )
      ]
    )
    (command.FuncDef
      name: add_upstream_commit
      body: 
        (command.BraceGroup
          children: [
            (command.AndOr
              ops: [Op_DAmp]
              children: [
                (command.Subshell
                  command_list: 
                    (command.CommandList
                      children: [
                        (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)
                                  op: Equal
                                  rhs: 
                                    {
                                      (word_part.CommandSubPart
                                        command_list: 
                                          (command.CommandList
                                            children: [(C {(git)} {(rev-parse)} {(--short)} {(HEAD)})]
                                          )
                                        left_token: <Left_CommandSub '$('>
                                      )
                                    }
                                )
                              ]
                            )
                            (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)
                                  op: Equal
                                  rhs: 
                                    {
                                      (word_part.CommandSubPart
                                        command_list: 
                                          (command.CommandList
                                            children: [(C {(git)} {(rev-parse)} {(--short)} {(HEAD)})]
                                          )
                                        left_token: <Left_CommandSub '$('>
                                      )
                                    }
                                )
                              ]
                            )
                            (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_DollarName '$pwd') (/submodule))}]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_DGreat '>>'>
                                  fd: 16777215
                                  arg_word: {(../expect.err)}
                                )
                              ]
                            )
                            (command.SimpleCommand
                              words: [
                                {(echo)}
                                {
                                  (DQ ('   ') ($ VSub_DollarName '$head1') (..) 
                                    ($ VSub_DollarName '$head2') ('  master     -> origin/master')
                                  )
                                }
                              ]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_DGreat '>>'>
                                  fd: 16777215
                                  arg_word: {(../expect.err)}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                )
                (command.Subshell
                  command_list: 
                    (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)
                                  op: Equal
                                  rhs: 
                                    {
                                      (word_part.CommandSubPart
                                        command_list: 
                                          (command.CommandList
                                            children: [(C {(git)} {(rev-parse)} {(--short)} {(HEAD)})]
                                          )
                                        left_token: <Left_CommandSub '$('>
                                      )
                                    }
                                )
                              ]
                            )
                            (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)
                                  op: Equal
                                  rhs: 
                                    {
                                      (word_part.CommandSubPart
                                        command_list: 
                                          (command.CommandList
                                            children: [(C {(git)} {(rev-parse)} {(--short)} {(HEAD)})]
                                          )
                                        left_token: <Left_CommandSub '$('>
                                      )
                                    }
                                )
                              ]
                            )
                            (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_DollarName '$pwd') (/deepsubmodule))}
                              ]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_DGreat '>>'>
                                  fd: 16777215
                                  arg_word: {(../expect.err)}
                                )
                              ]
                            )
                            (command.SimpleCommand
                              words: [
                                {(echo)}
                                {
                                  (DQ ('   ') ($ VSub_DollarName '$head1') (..) 
                                    ($ VSub_DollarName '$head2') ('  master     -> origin/master')
                                  )
                                }
                              ]
                              redirects: [
                                (redir.Redir
                                  op: <Redir_DGreat '>>'>
                                  fd: 16777215
                                  arg_word: {(../expect.err)}
                                )
                              ]
                            )
                          ]
                        )
                      ]
                    )
                )
              ]
            )
          ]
        )
    )
    (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)})
  ]
)