This series fixes several buggy tests which went undetected due to
broken &&-chains in subshells, modernizes some tests to take advantage
of test functions (test_might_fail(), test_write_lines(), etc.), and
fixes a lot of broken &&-chains in subshells. It applies atop
'master'. Happily, there are no broken &&-chains in subshells in any
in-flight topic.
It is split out from an earlier series[1] which additionally extended
--chain-lint to work within subshells. I decided to make this an
independent series because these (hopefully) non-controversial changes
all stand on their own merit, and because I don't want to flood the list
repeatedly with this lengthy series as I re-roll the "extend
--chain-lint to work in subshells" functionality from [1].

To ease review burden, I largely avoided noisy modernizations and
cleanups, and limited changes to merely adding "&&" even when some other
transformation would have made the fix nicer overall. (For example, I
resisted the urge to replace a series of 'echo' statements with a simple
here-doc.)

Changes since [1]:

* Found and fixed more &&-chain breakage, and converted a couple more
  'unset' instances (which were hidden behind a MINGW prerequisite) to
  sane_unset().

* Rewrote commit messages to sell changes on their own merit rather than
  leaning on --chain-lint as a crutch. (junio, jrnieder)

* Changed a modernization/cleanup to use "! non-git-command" rather than
  test_must_fail(), moving it to its own patch in the process. (j6t)

* Changed "printf '%s\n'" idiom to test_write_lines(). (junio)

* Incorporated Stefan's fix[2] for a broken 't/lib-submodule-update'
  test since my interpretation of the problem was incorrect.

* Converted a subshell 'echo' sequence to write_script().

* Dropped patches which existed primarily to pacify --chain-lint; they
  are no longer needed since I re-wrote the "linter" to detect &&-chain
  breakage itself (by pure textual inspection) rather than by
  incorporating subshell bodies into the main &&-chain:

  t0001: use "{...}" block around "||" expression rather than subshell
  t3303: use standard here-doc tag "EOF" to avoid fooling --chain-lint
  t9104: use "{...}" block around "||" expression rather than subshell
  t9401: drop unnecessary nested subshell

* Dropped a patch which pretty much duplicated Junio's 037714252f
  (tests: clean after SANITY tests, 2018-06-15), which graduated to
  'master':

  t7508: use test_when_finished() instead of managing exit code manually

An interdiff against [1] is below, although I stripped out all the noisy
"printf '%s\n'" to test_write_lines() differences, of which there were a
lot, since they drowned out the other more significant changes.

Thanks to Elijah, Hannes, Jonathan Nieder, Jonathan Tan, Junio, Luke,
Peff, and Stefan for comments on [1].

[1]: https://public-inbox.org/git/20180626073001.6555-1-sunsh...@sunshineco.com/
[2]: https://public-inbox.org/git/20180627183057.254467-1-sbel...@google.com/

Eric Sunshine (25):
  t: use test_might_fail() instead of manipulating exit code manually
  t: use test_write_lines() instead of series of 'echo' commands
  t: use sane_unset() rather than 'unset' with broken &&-chain
  t: drop unnecessary terminating semicolon in subshell
  t/lib-submodule-update: fix "absorbing" test
  t5405: use test_must_fail() instead of checking exit code manually
  t5406: use write_script() instead of birthing shell script manually
  t5505: modernize and simplify hard-to-digest test
  t6036: fix broken "merge fails but has appropriate contents" tests
  t7201: drop pointless "exit 0" at end of subshell
  t7400: fix broken "submodule add/reconfigure --force" test
  t7810: use test_expect_code() instead of hand-rolled comparison
  t9001: fix broken "invoke hook" test
  t9814: simplify convoluted check that command correctly errors out
  t0000-t0999: fix broken &&-chains
  t1000-t1999: fix broken &&-chains
  t2000-t2999: fix broken &&-chains
  t3000-t3999: fix broken &&-chains
  t3030: fix broken &&-chains
  t4000-t4999: fix broken &&-chains
  t5000-t5999: fix broken &&-chains
  t6000-t6999: fix broken &&-chains
  t7000-t7999: fix broken &&-chains
  t9000-t9999: fix broken &&-chains
  t9119: fix broken &&-chains

 t/lib-submodule-update.sh                     |   5 +-
 t/t0000-basic.sh                              |   2 +-
 t/t0001-init.sh                               |   4 +-
 t/t0003-attributes.sh                         |  24 +-
 t/t0021-conversion.sh                         |   4 +-
 t/t0090-cache-tree.sh                         |   2 +-
 t/t1004-read-tree-m-u-wf.sh                   |   8 +-
 t/t1005-read-tree-reset.sh                    |  10 +-
 t/t1008-read-tree-overlay.sh                  |   2 +-
 t/t1020-subdirectory.sh                       |   2 +-
 t/t1050-large.sh                              |   6 +-
 t/t1300-config.sh                             |   2 +-
 t/t1411-reflog-show.sh                        |   6 +-
 t/t1507-rev-parse-upstream.sh                 |   6 +-
 t/t1512-rev-parse-disambiguation.sh           |   6 +-
 t/t1700-split-index.sh                        |   2 +-
 t/t2016-checkout-patch.sh                     |  24 +-
 t/t2103-update-index-ignore-missing.sh        |   2 +-
 t/t2202-add-addremove.sh                      |  14 +-
 t/t3000-ls-files-others.sh                    |   2 +-
 t/t3006-ls-files-long.sh                      |   2 +-
 t/t3008-ls-files-lazy-init-name-hash.sh       |   8 +-
 t/t3030-merge-recursive.sh                    | 340 +++++++++---------
 t/t3050-subprojects-fetch.sh                  |   8 +-
 t/t3102-ls-tree-wildcards.sh                  |   2 +-
 t/t3210-pack-refs.sh                          |   4 +-
 t/t3301-notes.sh                              |   8 +-
 t/t3400-rebase.sh                             |   8 +-
 t/t3402-rebase-merge.sh                       |   4 +-
 t/t3404-rebase-interactive.sh                 |   6 +-
 t/t3418-rebase-continue.sh                    |   4 +-
 t/t3700-add.sh                                |   8 +-
 t/t3701-add-interactive.sh                    |  16 +-
 t/t3904-stash-patch.sh                        |   8 +-
 t/t4001-diff-rename.sh                        |   2 +-
 t/t4010-diff-pathspec.sh                      |   4 +-
 t/t4012-diff-binary.sh                        |   6 +-
 t/t4024-diff-optimize-common.sh               |  16 +-
 t/t4025-hunk-header.sh                        |   8 +-
 t/t4041-diff-submodule-option.sh              |   4 +-
 t/t4060-diff-submodule-option-diff-format.sh  |   2 +-
 t/t4121-apply-diffs.sh                        |   2 +-
 t/t5300-pack-object.sh                        |   2 +-
 t/t5302-pack-index.sh                         |   2 +-
 t/t5400-send-pack.sh                          |   4 +-
 t/t5401-update-hooks.sh                       |   4 +-
 t/t5405-send-pack-rewind.sh                   |   3 +-
 t/t5406-remote-rejects.sh                     |   5 +-
 t/t5500-fetch-pack.sh                         |   2 +-
 t/t5505-remote.sh                             |  10 +-
 t/t5512-ls-remote.sh                          |   4 +-
 t/t5516-fetch-push.sh                         |  10 +-
 t/t5517-push-mirror.sh                        |  10 +-
 t/t5526-fetch-submodules.sh                   |   2 +-
 t/t5531-deep-submodule-push.sh                |   2 +-
 t/t5543-atomic-push.sh                        |   2 +-
 t/t5601-clone.sh                              |   2 +-
 t/t5605-clone-local.sh                        |   2 +-
 t/t5801-remote-helpers.sh                     |   2 +-
 t/t6010-merge-base.sh                         |   2 +-
 t/t6029-merge-subtree.sh                      |  16 +-
 t/t6036-recursive-corner-cases.sh             |  14 +-
 t/t6042-merge-rename-corner-cases.sh          |   8 +-
 t/t6043-merge-rename-directories.sh           |   2 +-
 t/t7001-mv.sh                                 |   2 +-
 t/t7105-reset-patch.sh                        |  12 +-
 t/t7201-co.sh                                 |  41 ++-
 t/t7301-clean-interactive.sh                  |  41 ++-
 t/t7400-submodule-basic.sh                    |  12 +-
 t/t7406-submodule-update.sh                   |   6 +-
 t/t7408-submodule-reference.sh                |   2 +-
 t/t7501-commit.sh                             |  56 +--
 t/t7506-status-submodule.sh                   |  10 +-
 t/t7610-mergetool.sh                          |   8 +-
 t/t7810-grep.sh                               |   7 +-
 t/t9001-send-email.sh                         |  10 +-
 t/t9100-git-svn-basic.sh                      |   2 +-
 t/t9101-git-svn-props.sh                      |   2 +-
 t/t9119-git-svn-info.sh                       | 120 +++----
 t/t9122-git-svn-author.sh                     |   6 +-
 t/t9129-git-svn-i18n-commitencoding.sh        |   2 +-
 t/t9130-git-svn-authors-file.sh               |   4 +-
 t/t9134-git-svn-ignore-paths.sh               |   6 +-
 t/t9137-git-svn-dcommit-clobber-series.sh     |   2 +-
 t/t9138-git-svn-authors-prog.sh               |   6 +-
 t/t9146-git-svn-empty-dirs.sh                 |  20 +-
 t/t9147-git-svn-include-paths.sh              |   6 +-
 t/t9152-svn-empty-dirs-after-gc.sh            |   2 +-
 t/t9164-git-svn-dcommit-concurrent.sh         |   2 +-
 ...65-git-svn-fetch-merge-branch-of-branch.sh |   2 +-
 t/t9200-git-cvsexportcommit.sh                |   6 +-
 t/t9302-fast-import-unpack-limit.sh           |   2 +-
 t/t9400-git-cvsserver-server.sh               |   8 +-
 t/t9600-cvsimport.sh                          |   2 +-
 t/t9806-git-p4-options.sh                     |   2 +-
 t/t9810-git-p4-rcs.sh                         |   2 +-
 t/t9811-git-p4-label-import.sh                |   2 +-
 t/t9814-git-p4-rename.sh                      |  18 +-
 t/t9815-git-p4-submit-fail.sh                 |   2 +-
 t/t9830-git-p4-symlink-dir.sh                 |   2 +-
 t/t9831-git-p4-triggers.sh                    |   2 +-
 t/t9902-completion.sh                         |   4 +-
 t/t9903-bash-prompt.sh                        |   2 +-
 103 files changed, 567 insertions(+), 589 deletions(-)

-- 
2.18.0.203.gfac676dfb9


Interdiff since [1]:

diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 8a2edee1cb..e90ec79087 100755
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -959,7 +959,7 @@ test_submodule_forced_switch_recursing_with_args () {
                )
        '
        # ... absorbing a .git directory.
-       test_expect_failure "$command: replace submodule containing a .git 
directory with a directory must fail" '
+       test_expect_success "$command: replace submodule containing a .git 
directory with a directory must fail" '
                prolog &&
                reset_work_tree_to_interested add_sub1 &&
                (
@@ -967,9 +967,8 @@ test_submodule_forced_switch_recursing_with_args () {
                        git branch -t replace_sub1_with_directory 
origin/replace_sub1_with_directory &&
                        replace_gitfile_with_git_dir sub1 &&
                        rm -rf .git/modules/sub1 &&
-                       test_must_fail $command replace_sub1_with_directory &&
+                       $command replace_sub1_with_directory &&
                        test_superproject_content 
origin/replace_sub1_with_directory &&
-                       test_submodule_content sub1 origin/modify_sub1 &&
                        test_git_directory_exists sub1
                )
        '
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 4c865051e7..ca85aae51e 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -408,7 +408,7 @@ is_hidden () {
 test_expect_success MINGW '.git hidden' '
        rm -rf newdir &&
        (
-               unset GIT_DIR GIT_WORK_TREE
+               sane_unset GIT_DIR GIT_WORK_TREE &&
                mkdir newdir &&
                cd newdir &&
                git init &&
@@ -420,7 +420,7 @@ test_expect_success MINGW '.git hidden' '
 test_expect_success MINGW 'bare git dir not hidden' '
        rm -rf newdir &&
        (
-               unset GIT_DIR GIT_WORK_TREE GIT_CONFIG
+               sane_unset GIT_DIR GIT_WORK_TREE GIT_CONFIG &&
                mkdir newdir &&
                cd newdir &&
                git --bare init
diff --git a/t/t1008-read-tree-overlay.sh b/t/t1008-read-tree-overlay.sh
index e74b185b6c..cf96016844 100755
--- a/t/t1008-read-tree-overlay.sh
+++ b/t/t1008-read-tree-overlay.sh
@@ -23,7 +23,7 @@ test_expect_success setup '
 
 test_expect_success 'multi-read' '
        read_tree_must_succeed initial master side &&
-       (echo a && echo b/c) >expect &&
+       test_write_lines a b/c >expect &&
        git ls-files >actual &&
        test_cmp expect actual
 '
diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh
index afa27ffe2d..724b4b9bc0 100755
--- a/t/t3210-pack-refs.sh
+++ b/t/t3210-pack-refs.sh
@@ -231,9 +231,9 @@ test_expect_success 'timeout if packed-refs.lock exists' '
 test_expect_success 'retry acquiring packed-refs.lock' '
        LOCK=.git/packed-refs.lock &&
        >"$LOCK" &&
-       test_when_finished "wait; rm -f $LOCK" &&
+       test_when_finished "wait && rm -f $LOCK" &&
        {
-               ( sleep 1 ; rm -f $LOCK ) &
+               ( sleep 1 && rm -f $LOCK ) &
        } &&
        git -c core.packedrefstimeout=3000 pack-refs --all --prune
 '
diff --git a/t/t4024-diff-optimize-common.sh b/t/t4024-diff-optimize-common.sh
index 7e76018296..6b44ce1493 100755
--- a/t/t4024-diff-optimize-common.sh
+++ b/t/t4024-diff-optimize-common.sh
@@ -127,17 +127,17 @@ test_expect_success setup '
 
        for n in $sample
        do
-               ( zs $n ; echo a ) >file-a$n &&
-               ( echo b; zs $n; echo ) >file-b$n &&
-               ( printf c; zs $n ) >file-c$n &&
-               ( echo d; zs $n ) >file-d$n &&
+               ( zs $n && echo a ) >file-a$n &&
+               ( echo b && zs $n && echo ) >file-b$n &&
+               ( printf c && zs $n ) >file-c$n &&
+               ( echo d && zs $n ) >file-d$n &&
 
                git add file-a$n file-b$n file-c$n file-d$n &&
 
-               ( zs $n ; echo A ) >file-a$n &&
-               ( echo B; zs $n; echo ) >file-b$n &&
-               ( printf C; zs $n ) >file-c$n &&
-               ( echo D; zs $n ) >file-d$n &&
+               ( zs $n && echo A ) >file-a$n &&
+               ( echo B && zs $n && echo ) >file-b$n &&
+               ( printf C && zs $n ) >file-c$n &&
+               ( echo D && zs $n ) >file-d$n &&
 
                expect_pattern $n || return 1
 
diff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh
index 350d2e6ea5..ff06f99649 100755
--- a/t/t5406-remote-rejects.sh
+++ b/t/t5406-remote-rejects.sh
@@ -6,8 +6,9 @@ test_description='remote push rejects are reported by client'
 
 test_expect_success 'setup' '
        mkdir .git/hooks &&
-       (echo "#!/bin/sh" && echo "exit 1") >.git/hooks/update &&
-       chmod +x .git/hooks/update &&
+       write_script .git/hooks/update <<-\EOF &&
+       exit 1
+       EOF
        echo 1 >file &&
        git add file &&
        git commit -m 1 &&
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index b141145fc2..f604ef7a72 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -886,7 +886,7 @@ test_expect_success 'submodule update properly revives a 
moved submodule' '
         git commit -am "pre move" &&
         H2=$(git rev-parse --short HEAD) &&
         git status | sed "s/$H/XXX/" >expect &&
-        H=$(cd submodule2; git rev-parse HEAD) &&
+        H=$(cd submodule2 && git rev-parse HEAD) &&
         git rm --cached submodule2 &&
         rm -rf submodule2 &&
         mkdir -p "moved/sub module" &&
diff --git a/t/t9146-git-svn-empty-dirs.sh b/t/t9146-git-svn-empty-dirs.sh
index 954948812c..5f91c0d68b 100755
--- a/t/t9146-git-svn-empty-dirs.sh
+++ b/t/t9146-git-svn-empty-dirs.sh
@@ -21,7 +21,7 @@ test_expect_success 'empty directories exist' '
                do
                        if ! test -d "$i"
                        then
-                               echo >&2 "$i does not exist"
+                               echo >&2 "$i does not exist" &&
                                exit 1
                        fi
                done
@@ -38,7 +38,7 @@ test_expect_success 'option automkdirs set to false' '
                do
                        if test -d "$i"
                        then
-                               echo >&2 "$i exists"
+                               echo >&2 "$i exists" &&
                                exit 1
                        fi
                done
@@ -63,7 +63,7 @@ test_expect_success 'git svn mkdirs recreates empty 
directories' '
                do
                        if ! test -d "$i"
                        then
-                               echo >&2 "$i does not exist"
+                               echo >&2 "$i does not exist" &&
                                exit 1
                        fi
                done
@@ -148,7 +148,7 @@ test_expect_success 'git svn gc-ed files work' '
                        do
                                if ! test -d "$i"
                                then
-                                       echo >&2 "$i does not exist"
+                                       echo >&2 "$i does not exist" &&
                                        exit 1
                                fi
                        done
diff --git a/t/t9152-svn-empty-dirs-after-gc.sh 
b/t/t9152-svn-empty-dirs-after-gc.sh
index 301e779709..89f285d082 100755
--- a/t/t9152-svn-empty-dirs-after-gc.sh
+++ b/t/t9152-svn-empty-dirs-after-gc.sh
@@ -30,7 +30,7 @@ test_expect_success 'git svn mkdirs recreates empty 
directories after git svn gc
                do
                        if ! test -d "$i"
                        then
-                               echo >&2 "$i does not exist"
+                               echo >&2 "$i does not exist" &&
                                exit 1
                        fi
                done
diff --git a/t/t9302-fast-import-unpack-limit.sh 
b/t/t9302-fast-import-unpack-limit.sh
index a04de14677..bb1c39cfcc 100755
--- a/t/t9302-fast-import-unpack-limit.sh
+++ b/t/t9302-fast-import-unpack-limit.sh
@@ -80,7 +80,7 @@ test_expect_success 'lookups after checkpoint works' '
                do
                        if test $n -gt 30
                        then
-                               echo >&2 "checkpoint did not update branch"
+                               echo >&2 "checkpoint did not update branch" &&
                                exit 1
                        else
                                n=$(($n + 1))
diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh
index 4207e9caa5..a5e5dca753 100755
--- a/t/t9400-git-cvsserver-server.sh
+++ b/t/t9400-git-cvsserver-server.sh
@@ -328,7 +328,7 @@ test_expect_success 'cvs update (subdirectories)' \
   '(for dir in A A/B A/B/C A/D E; do
       mkdir $dir &&
       echo "test file in $dir" >"$dir/file_in_$(echo $dir|sed -e "s#/# #g")"  
&&
-      git add $dir;
+      git add $dir
    done) &&
    git commit -q -m "deep sub directory structure" &&
    git push gitcvs.git >/dev/null &&
diff --git a/t/t9814-git-p4-rename.sh b/t/t9814-git-p4-rename.sh
index 80aac5ab16..60baa06e27 100755
--- a/t/t9814-git-p4-rename.sh
+++ b/t/t9814-git-p4-rename.sh
@@ -9,11 +9,11 @@ test_expect_success 'start p4d' '
 '
 
 # We rely on this behavior to detect for p4 move availability.
-test_expect_success 'p4 help unknown returns 1' '
+test_expect_success '"p4 help unknown" errors out' '
        (
                cd "$cli" &&
                p4 help client &&
-               test_must_fail p4 help nosuchcommand
+               ! p4 help nosuchcommand
        )
 '

Reply via email to