(CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <"Recursive \"git fetch\" for submodules">)} spids: [7] ) ] spids: [7] ) (C {(.)} {(./test-lib.sh)}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:pwd) op: Equal rhs: { (CommandSubPart command_list: (CommandList children:[(C {(pwd)})]) left_token: <Left_CommandSub "$("> spids: [19 21] ) } spids: [18] ) ] spids: [18] ) (FuncDef name: add_upstream_commit body: (BraceGroup children: [ (AndOr children: [ (Subshell child: (AndOr children: [ (C {(cd)} {(submodule)}) (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:head1) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [(C {(git)} {(rev-parse)} {(--short)} {(HEAD)})] ) left_token: <Left_CommandSub "$("> spids: [42 50] ) } spids: [41] ) ] spids: [41] ) (AndOr children: [ (SimpleCommand words: [{(echo)} {(new)}] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(subfile)} spids: [59] ) ] ) (AndOr children: [ (C {(test_tick)}) (AndOr children: [ (C {(git)} {(add)} {(subfile)}) (AndOr children: [ (C {(git)} {(commit)} {(-m)} {(new)} {(subfile)}) (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:head2) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (C {(git)} {(rev-parse)} {(--short)} {(HEAD)} ) ] ) left_token: <Left_CommandSub "$("> spids: [94 102] ) } spids: [93] ) ] spids: [93] ) (AndOr children: [ (SimpleCommand words: [ {(echo)} {(DQ ("Fetching submodule submodule"))} ] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(../expect.err)} spids: [113] ) ] ) (AndOr children: [ (SimpleCommand words: [ {(echo)} { (DQ ("From ") ($ VSub_Name "$pwd") (/submodule) ) } ] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(../expect.err)} spids: [128] ) ] ) (SimpleCommand words: [ {(echo)} { (DQ (" ") ($ VSub_Name "$head1") (..) ($ VSub_Name "$head2") (" master -> origin/master") ) } ] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(../expect.err)} spids: [145] ) ] ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) spids: [31 150] ) (Subshell child: (CommandList children: [ (AndOr children: [ (C {(cd)} {(deepsubmodule)}) (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:head1) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (C {(git)} {(rev-parse)} {(--short)} {(HEAD)}) ] ) left_token: <Left_CommandSub "$("> spids: [166 174] ) } spids: [165] ) ] spids: [165] ) (AndOr children: [ (SimpleCommand words: [{(echo)} {(new)}] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(deepsubfile)} spids: [183] ) ] ) (AndOr children: [ (C {(test_tick)}) (AndOr children: [ (C {(git)} {(add)} {(deepsubfile)}) (AndOr children: [ (C {(git)} {(commit)} {(-m)} {(new)} {(deepsubfile)}) (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:head2) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (C {(git)} {(rev-parse)} {(--short)} {(HEAD)} ) ] ) left_token: <Left_CommandSub "$("> spids: [218 226] ) } spids: [217] ) ] spids: [217] ) (SimpleCommand words: [ {(echo)} { (DQ ( "Fetching submodule submodule/subdir/deepsubmodule" ) ) } ] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(../expect.err)} spids: [237] ) ] ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) (AndOr children: [ (SimpleCommand words: [{(echo)} {(DQ ("From ") ($ VSub_Name "$pwd") (/deepsubmodule))}] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(../expect.err)} spids: [250] ) ] ) (SimpleCommand words: [ {(echo)} { (DQ (" ") ($ VSub_Name "$head1") (..) ($ VSub_Name "$head2") (" master -> origin/master") ) } ] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(../expect.err)} spids: [267] ) ] ) ] op_id: Op_DAmp ) ] ) spids: [155 272] ) ] op_id: Op_DAmp ) ] spids: [28] ) spids: [24 27] ) (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)}) ] )