git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 0/6] tests: fix ignored & hidden exit codes
@ 2022-07-21  6:51 Ævar Arnfjörð Bjarmason
  2022-07-21  6:51 ` [PATCH 1/6] diff tests: fix ignored exit codes in t4023 Ævar Arnfjörð Bjarmason
                   ` (6 more replies)
  0 siblings, 7 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-07-21  6:51 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

A small set of fixes to correct git on the LHS of a pipe, and in $()
within a "test" expression, or where its exit code is otherwise
hidden.

This also includes a (reworded) version of a case where we exit'd out
of test-lib.sh itself, which Junio requested by spun off in:
https://lore.kernel.org/git/xmqqmtd33e1h.fsf@gitster.g/

As noted in [1] there's no need to rebase the other series on top of
this, it benefits from 6/6 here, but the two can proceed
independently.

This is still just the tip of the iceberg in terms of hidden exit
codes in the test suite, as can be seen with e.g.:

	git grep 'test.*\$\((git|test-tool)' -- 't/*.sh'

But these are all cases I've run into actual issues with, almost all
when testing with SANITIZE=leak. In most cases just with one of the
hunks in a given commit, but then I converted the rest of the file to
fix a similar bad pattern.

That doesn't mean that these are more important than e.g. the output
of the "grep" above, but we've got to start somewhere...

The range-diff below is to the tip of [2], to show how 6/6 was
reworded.

1. https://lore.kernel.org/git/cover-v2-00.14-00000000000-20220720T211221Z-avarab@gmail.com/
2. https://lore.kernel.org/git/cover-00.10-00000000000-20220719T205710Z-avarab@gmail.com/

Ævar Arnfjörð Bjarmason (6):
  diff tests: fix ignored exit codes in t4023
  t/lib-patch-mode.sh: fix ignored "git" exit codes
  auto-crlf tests: check "git checkout" exit code
  test-lib-functions: add and use test_cmp_cmd
  merge tests: don't ignore "rev-parse" exit code in helper
  log tests: don't use "exit 1" outside a sub-shell

 t/lib-patch-mode.sh               | 13 ++++++---
 t/t0027-auto-crlf.sh              | 14 +++++++---
 t/t0060-path-utils.sh             | 45 +++++++++++++++++--------------
 t/t4023-diff-rename-typechange.sh | 12 ++++-----
 t/t4205-log-pretty-formats.sh     |  2 +-
 t/t7600-merge.sh                  |  9 +++----
 t/test-lib-functions.sh           | 18 +++++++++++++
 7 files changed, 74 insertions(+), 39 deletions(-)

Range-diff:
-:  ----------- > 1:  f8a382841d5 diff tests: fix ignored exit codes in t4023
-:  ----------- > 2:  85c6ab40e91 t/lib-patch-mode.sh: fix ignored "git" exit codes
-:  ----------- > 3:  cfc1abbf7e3 auto-crlf tests: check "git checkout" exit code
-:  ----------- > 4:  df1b674b8a7 test-lib-functions: add and use test_cmp_cmd
-:  ----------- > 5:  563666f9426 merge tests: don't ignore "rev-parse" exit code in helper
1:  9cedf0cb0e2 ! 6:  259b4618fcb log tests: don't use "exit 1" outside a sub-shell
    @@ Commit message
         Using "exit 1" outside a sub-shell will cause the test framework
         itself to exit on failure, which isn't what we want to do here.
     
    -    This issue was spotted with the new
    -    "GIT_TEST_PASSING_SANITIZE_LEAK=check" mode, i.e. that "git show"
    -    command leaks memory, and we'd thus "exit 1". Another implementation
    -    of "GIT_TEST_PASSING_SANITIZE_LEAK=check" or "--invert-exit-code"
    -    might have intercepted the "exit 1", and thus hidden the underlying
    -    issue here, but we correctly distinguish the two.
    +    This issue was spotted with the in-flight
    +    "GIT_TEST_PASSING_SANITIZE_LEAK=check" test mode[1]. This "git show"
    +    invocation currently leaks memory, and we'd thus "exit 1". This change
    +    was initially part of that topic[2] to demonstrate the correctness of
    +    the "check" implementation.
    +
    +    1. https://lore.kernel.org/git/patch-07.10-0961df2ab6c-20220719T205710Z-avarab@gmail.com/
    +    2. https://lore.kernel.org/git/patch-10.10-9cedf0cb0e2-20220719T205710Z-avarab@gmail.com/
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
-- 
2.37.1.1095.g64a1e8362fd


^ permalink raw reply	[flat|nested] 83+ messages in thread

* [PATCH 1/6] diff tests: fix ignored exit codes in t4023
  2022-07-21  6:51 [PATCH 0/6] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
@ 2022-07-21  6:51 ` Ævar Arnfjörð Bjarmason
  2022-07-21  6:51 ` [PATCH 2/6] t/lib-patch-mode.sh: fix ignored "git" exit codes Ævar Arnfjörð Bjarmason
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-07-21  6:51 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

Change a "git diff-tree" command to be &&-chained so that we won't
ignore its exit code, see the ea05fd5fbf7 (Merge branch
'ab/keep-git-exit-codes-in-tests', 2022-03-16) topic for prior art.

This fixes code added in b45563a229f (rename: Break filepairs with
different types., 2007-11-30). Due to hiding the exit code we hid a
memory leak under SANITIZE=leak.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t4023-diff-rename-typechange.sh | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh
index 7cb99092938..25c31b0cb1b 100755
--- a/t/t4023-diff-rename-typechange.sh
+++ b/t/t4023-diff-rename-typechange.sh
@@ -52,8 +52,8 @@ test_expect_success setup '
 '
 
 test_expect_success 'cross renames to be detected for regular files' '
-
-	git diff-tree five six -r --name-status -B -M | sort >actual &&
+	git diff-tree five six -r --name-status -B -M >out &&
+	sort <out >actual &&
 	{
 		echo "R100	foo	bar" &&
 		echo "R100	bar	foo"
@@ -63,8 +63,8 @@ test_expect_success 'cross renames to be detected for regular files' '
 '
 
 test_expect_success 'cross renames to be detected for typechange' '
-
-	git diff-tree one two -r --name-status -B -M | sort >actual &&
+	git diff-tree one two -r --name-status -B -M >out &&
+	sort <out >actual &&
 	{
 		echo "R100	foo	bar" &&
 		echo "R100	bar	foo"
@@ -74,8 +74,8 @@ test_expect_success 'cross renames to be detected for typechange' '
 '
 
 test_expect_success 'moves and renames' '
-
-	git diff-tree three four -r --name-status -B -M | sort >actual &&
+	git diff-tree three four -r --name-status -B -M >out &&
+	sort <out >actual &&
 	{
 		# see -B -M (#6) in t4008
 		echo "C100	foo	bar" &&
-- 
2.37.1.1095.g64a1e8362fd


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH 2/6] t/lib-patch-mode.sh: fix ignored "git" exit codes
  2022-07-21  6:51 [PATCH 0/6] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
  2022-07-21  6:51 ` [PATCH 1/6] diff tests: fix ignored exit codes in t4023 Ævar Arnfjörð Bjarmason
@ 2022-07-21  6:51 ` Ævar Arnfjörð Bjarmason
  2022-07-21  6:51 ` [PATCH 3/6] auto-crlf tests: check "git checkout" exit code Ævar Arnfjörð Bjarmason
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-07-21  6:51 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

Fix code added in b319ef70a94 (Add a small patch-mode testing library,
2009-08-13) to use &&-chaining and test_cmp instead of interpolating
"git" commands in a "test" statement.

This fixes cases where we'd have e.g. missed memory leaks under
SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
discovered it while looking at leaks in related code.

The "cat _head >expect" here is redundant, we could simply give
"_head" to "test_cmp", but let's be consistent in using the "expect"
and "actual" names for clarity.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-patch-mode.sh | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/t/lib-patch-mode.sh b/t/lib-patch-mode.sh
index cfd76bf987b..887554933c2 100644
--- a/t/lib-patch-mode.sh
+++ b/t/lib-patch-mode.sh
@@ -29,8 +29,13 @@ set_and_save_state () {
 
 # verify_state <path> <expected-worktree-content> <expected-index-content>
 verify_state () {
-	test "$(cat "$1")" = "$2" &&
-	test "$(git show :"$1")" = "$3"
+	echo "$2" >expect &&
+	cat "$1" >actual &&
+	test_cmp expect actual &&
+
+	echo "$3" >expect
+	git show :"$1" >actual &&
+	test_cmp expect actual
 }
 
 # verify_saved_state <path>
@@ -46,5 +51,7 @@ save_head () {
 }
 
 verify_saved_head () {
-	test "$(cat _head)" = "$(git rev-parse HEAD)"
+	cat _head >expect &&
+	git rev-parse HEAD >actual &&
+	test_cmp expect actual
 }
-- 
2.37.1.1095.g64a1e8362fd


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH 3/6] auto-crlf tests: check "git checkout" exit code
  2022-07-21  6:51 [PATCH 0/6] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
  2022-07-21  6:51 ` [PATCH 1/6] diff tests: fix ignored exit codes in t4023 Ævar Arnfjörð Bjarmason
  2022-07-21  6:51 ` [PATCH 2/6] t/lib-patch-mode.sh: fix ignored "git" exit codes Ævar Arnfjörð Bjarmason
@ 2022-07-21  6:51 ` Ævar Arnfjörð Bjarmason
  2022-07-21  6:51 ` [PATCH 4/6] test-lib-functions: add and use test_cmp_cmd Ævar Arnfjörð Bjarmason
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-07-21  6:51 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

Don't hide the exit code from the "git checkout" we run to checkout
our attributes file.

This fixes cases where we'd have e.g. missed memory leaks under
SANITIZE=leak, this code doesn't leak (the relevant "git checkout"
leak has been fixed), but in a past version of git we'd continue past
this failure under SANITIZE=leak when these invocations had errored
out, even under "--immediate".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0027-auto-crlf.sh | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index 7f80f463930..03b955b774f 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -293,11 +293,17 @@ checkout_files () {
 	pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
 	for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
 	do
-		rm crlf_false_attr__$f.txt &&
-		if test -z "$ceol"; then
-			git checkout -- crlf_false_attr__$f.txt
+		if test -z "$ceol"
+		then
+			test_expect_success "setup $f checkout" '
+				rm crlf_false_attr__$f.txt &&
+				git checkout -- crlf_false_attr__$f.txt
+			'
 		else
-			git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
+			test_expect_success "setup $f checkout with core.eol=$ceol" '
+				rm crlf_false_attr__$f.txt &&
+				git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
+			'
 		fi
 	done
 
-- 
2.37.1.1095.g64a1e8362fd


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH 4/6] test-lib-functions: add and use test_cmp_cmd
  2022-07-21  6:51 [PATCH 0/6] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                   ` (2 preceding siblings ...)
  2022-07-21  6:51 ` [PATCH 3/6] auto-crlf tests: check "git checkout" exit code Ævar Arnfjörð Bjarmason
@ 2022-07-21  6:51 ` Ævar Arnfjörð Bjarmason
  2022-07-21  6:51 ` [PATCH 5/6] merge tests: don't ignore "rev-parse" exit code in helper Ævar Arnfjörð Bjarmason
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-07-21  6:51 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

Add a "test_cmp_cmd" helper for the common pattern discussed in the
documentation being added here to "t/test-lib-functions.sh".

This implementation leaves the door open for extending this helper
past its obvious limitations, such as:

	test_cmp_cmd "some" "lines" -- <some-cmd>
	test_cmp_cmd --stdin <some-cmd> <expect
	test_cmp_cmd --ignore-stderr "output" <some-cmd>

By using this in t0060-path.sh we'll catch cases where "git" or
"test-tool" errors (such as segfaults or abort()) were previously
hidden, and we'd either pass the test, or fail in some subsequent
assertion.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0060-path-utils.sh   | 45 +++++++++++++++++++++++------------------
 t/test-lib-functions.sh | 18 +++++++++++++++++
 2 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 1f2007e62b7..6f278417e83 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -10,8 +10,11 @@ TEST_PASSES_SANITIZE_LEAK=true
 
 norm_path() {
 	expected=$(test-tool path-utils print_path "$2")
-	test_expect_success $3 "normalize path: $1 => $2" \
-	"test \"\$(test-tool path-utils normalize_path_copy '$1')\" = '$expected'"
+	test_expect_success $3 "normalize path: $1 => $2" "
+		echo '$expected' >expect &&
+		test-tool path-utils normalize_path_copy '$1' >actual &&
+		test_cmp expect actual
+	"
 }
 
 relative_path() {
@@ -166,8 +169,10 @@ ancestor D:/Users/me C:/ -1 MINGW
 ancestor //server/share/my-directory //server/share/ 14 MINGW
 
 test_expect_success 'strip_path_suffix' '
-	test c:/msysgit = $(test-tool path-utils strip_path_suffix \
-		c:/msysgit/libexec//git-core libexec/git-core)
+	echo c:/msysgit >expect &&
+	test-tool path-utils strip_path_suffix \
+		c:/msysgit/libexec//git-core libexec/git-core >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'absolute path rejects the empty string' '
@@ -189,34 +194,34 @@ test_expect_success 'real path rejects the empty string' '
 
 test_expect_success POSIX 'real path works on absolute paths 1' '
 	nopath="hopefully-absent-path" &&
-	test "/" = "$(test-tool path-utils real_path "/")" &&
-	test "/$nopath" = "$(test-tool path-utils real_path "/$nopath")"
+	test_cmp_cmd / test-tool path-utils real_path "/" &&
+	test_cmp_cmd "/$nopath" test-tool path-utils real_path "/$nopath"
 '
 
 test_expect_success 'real path works on absolute paths 2' '
 	nopath="hopefully-absent-path" &&
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "$d")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "$d/$nopath")"
+	test_cmp_cmd "$d" test-tool path-utils real_path "$d" &&
+	test_cmp_cmd "$d/$nopath" test-tool path-utils real_path "$d/$nopath"
 '
 
 test_expect_success POSIX 'real path removes extra leading slashes' '
 	nopath="hopefully-absent-path" &&
-	test "/" = "$(test-tool path-utils real_path "///")" &&
-	test "/$nopath" = "$(test-tool path-utils real_path "///$nopath")" &&
+	test_cmp_cmd "/" test-tool path-utils real_path "///" &&
+	test_cmp_cmd "/$nopath" test-tool path-utils real_path "///$nopath" &&
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "//$d")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "//$d/$nopath")"
+	test_cmp_cmd "$d" test-tool path-utils real_path "//$d" &&
+	test_cmp_cmd "$d/$nopath" test-tool path-utils real_path "//$d/$nopath"
 '
 
 test_expect_success 'real path removes other extra slashes' '
 	nopath="hopefully-absent-path" &&
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "$d///")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "$d///$nopath")"
+	test_cmp_cmd "$d" test-tool path-utils real_path "$d///" &&
+	test_cmp_cmd "$d/$nopath" test-tool path-utils real_path "$d///$nopath"
 '
 
 test_expect_success SYMLINKS 'real path works on symlinks' '
@@ -227,19 +232,19 @@ test_expect_success SYMLINKS 'real path works on symlinks' '
 	mkdir third &&
 	dir="$(cd .git && pwd -P)" &&
 	dir2=third/../second/other/.git &&
-	test "$dir" = "$(test-tool path-utils real_path $dir2)" &&
+	test_cmp_cmd "$dir" test-tool path-utils real_path $dir2 &&
 	file="$dir"/index &&
-	test "$file" = "$(test-tool path-utils real_path $dir2/index)" &&
+	test_cmp_cmd "$file" test-tool path-utils real_path $dir2/index &&
 	basename=blub &&
-	test "$dir/$basename" = "$(cd .git && test-tool path-utils real_path "$basename")" &&
+	test_cmp_cmd "$dir/$basename" test-tool -C .git path-utils real_path "$basename" &&
 	ln -s ../first/file .git/syml &&
 	sym="$(cd first && pwd -P)"/file &&
-	test "$sym" = "$(test-tool path-utils real_path "$dir2/syml")"
+	test_cmp_cmd "$sym" test-tool path-utils real_path "$dir2/syml"
 '
 
 test_expect_success SYMLINKS 'prefix_path works with absolute paths to work tree symlinks' '
 	ln -s target symlink &&
-	test "$(test-tool path-utils prefix_path prefix "$(pwd)/symlink")" = "symlink"
+	test_cmp_cmd "symlink" test-tool path-utils prefix_path prefix "$(pwd)/symlink"
 '
 
 test_expect_success 'prefix_path works with only absolute path to work tree' '
@@ -255,7 +260,7 @@ test_expect_success 'prefix_path rejects absolute path to dir with same beginnin
 test_expect_success SYMLINKS 'prefix_path works with absolute path to a symlink to work tree having  same beginning as work tree' '
 	git init repo &&
 	ln -s repo repolink &&
-	test "a" = "$(cd repo && test-tool path-utils prefix_path prefix "$(pwd)/../repolink/a")"
+	test_cmp_cmd "a" test-tool -C repo path-utils prefix_path prefix "$(cd repo && pwd)/../repolink/a"
 '
 
 relative_path /foo/a/b/c/	/foo/a/b/	c/
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 6da7273f1d5..63e46442eb6 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1366,6 +1366,24 @@ test_cmp_rev () {
 	fi
 }
 
+# test_cmp_cmd is a convenience helper for doing the more verbose:
+#
+#	echo something >expect &&
+#	<some-command-and-args> >actual &&
+#	test_cmp expect actual
+#
+# As:
+#
+#	test_cmp_cmd something <some-command-and-args>
+test_cmp_cmd () {
+	local expect="$1" &&
+	shift &&
+	printf "%s\n" "$expect" >expect &&
+	"$@" >actual 2>err &&
+	test_must_be_empty err
+	test_cmp expect actual
+}
+
 # Compare paths respecting core.ignoreCase
 test_cmp_fspath () {
 	if test "x$1" = "x$2"
-- 
2.37.1.1095.g64a1e8362fd


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH 5/6] merge tests: don't ignore "rev-parse" exit code in helper
  2022-07-21  6:51 [PATCH 0/6] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                   ` (3 preceding siblings ...)
  2022-07-21  6:51 ` [PATCH 4/6] test-lib-functions: add and use test_cmp_cmd Ævar Arnfjörð Bjarmason
@ 2022-07-21  6:51 ` Ævar Arnfjörð Bjarmason
  2022-07-21  6:51 ` [PATCH 6/6] log tests: don't use "exit 1" outside a sub-shell Ævar Arnfjörð Bjarmason
  2022-12-02  0:06 ` [PATCH v2 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
  6 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-07-21  6:51 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

Change the verify_mergeheads() helper the check the exit code of "git
rev-parse". The "$rest" variable added in 274a5c06d52 (merge: record
tag objects without peeling in MERGE_HEAD, 2011-11-07) wasn't being
used.

Such a thing is needed to support the .git/MERGE_HEAD format in
general, but in this case we have no such addition to the line. So
let's compare with "test_cmp" instead, we can always add back this
"$rest" parsing if it's needed in the future.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t7600-merge.sh | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index f0f6fda150b..3682d6f9d4e 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -102,12 +102,11 @@ verify_parents () {
 }
 
 verify_mergeheads () {
-	test_write_lines "$@" >mergehead.expected &&
-	while read sha1 rest
+	for rev in "$@"
 	do
-		git rev-parse $sha1
-	done <.git/MERGE_HEAD >mergehead.actual &&
-	test_cmp mergehead.expected mergehead.actual
+		git rev-parse $rev || return 1
+	done >mergehead.expected &&
+	test_cmp mergehead.expected .git/MERGE_HEAD
 }
 
 verify_no_mergehead () {
-- 
2.37.1.1095.g64a1e8362fd


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH 6/6] log tests: don't use "exit 1" outside a sub-shell
  2022-07-21  6:51 [PATCH 0/6] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                   ` (4 preceding siblings ...)
  2022-07-21  6:51 ` [PATCH 5/6] merge tests: don't ignore "rev-parse" exit code in helper Ævar Arnfjörð Bjarmason
@ 2022-07-21  6:51 ` Ævar Arnfjörð Bjarmason
  2022-12-02  0:06 ` [PATCH v2 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
  6 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-07-21  6:51 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

Change an "exit 1" added in ac52d9410e5 (t4205: cover `git log
--reflog -z` blindspot, 2019-11-19) to use "return 1" instead, which
curiously was done in an adjacent test case added in the same commit.

Using "exit 1" outside a sub-shell will cause the test framework
itself to exit on failure, which isn't what we want to do here.

This issue was spotted with the in-flight
"GIT_TEST_PASSING_SANITIZE_LEAK=check" test mode[1]. This "git show"
invocation currently leaks memory, and we'd thus "exit 1". This change
was initially part of that topic[2] to demonstrate the correctness of
the "check" implementation.

1. https://lore.kernel.org/git/patch-07.10-0961df2ab6c-20220719T205710Z-avarab@gmail.com/
2. https://lore.kernel.org/git/patch-10.10-9cedf0cb0e2-20220719T205710Z-avarab@gmail.com/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t4205-log-pretty-formats.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index e448ef2928a..0404491d6ee 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -156,7 +156,7 @@ test_expect_success 'NUL termination with --reflog --pretty=oneline' '
 	for r in $revs
 	do
 		git show -s --pretty=oneline "$r" >raw &&
-		cat raw | lf_to_nul || exit 1
+		cat raw | lf_to_nul || return 1
 	done >expect &&
 	# the trailing NUL is already produced so we do not need to
 	# output another one
-- 
2.37.1.1095.g64a1e8362fd


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v2 0/8] tests: fix ignored & hidden exit codes
  2022-07-21  6:51 [PATCH 0/6] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                   ` (5 preceding siblings ...)
  2022-07-21  6:51 ` [PATCH 6/6] log tests: don't use "exit 1" outside a sub-shell Ævar Arnfjörð Bjarmason
@ 2022-12-02  0:06 ` Ævar Arnfjörð Bjarmason
  2022-12-02  0:06   ` [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell Ævar Arnfjörð Bjarmason
                     ` (8 more replies)
  6 siblings, 9 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02  0:06 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

A small set of fixes to correct git on the LHS of a pipe, and in $()
within a "test" expression, or where its exit code is otherwise
hidden.

The 1/8 here was originally submitted as part of another series, and
what prompted this re-submission at this time is that the exact same
fix was independently discovered in [2].

This is still just the tip of the iceberg in terms of these issues in
the test suite, but hopefully this will get some attention this time
around.

1. https://lore.kernel.org/git/xmqqmtd33e1h.fsf@gitster.g/
2. https://lore.kernel.org/git/c5b4d091-23c1-5a75-a255-99ec83973d8d@web.de/

Ævar Arnfjörð Bjarmason (8):
  log tests: don't use "exit 1" outside a sub-shell
  auto-crlf tests: check "git checkout" exit code
  diff tests: fix ignored exit codes in t4023
  test-lib-functions: add and use test_cmp_cmd
  t/lib-patch-mode.sh: fix ignored "git" exit codes
  merge tests: don't ignore "rev-parse" exit code in helper
  tests: use "test_cmp_cmd" instead of "test" in sub-shells
  tests: use "test_cmp_cmd" in misc tests

 t/lib-httpd.sh                     |  3 +-
 t/lib-patch-mode.sh                |  9 +++--
 t/lib-submodule-update.sh          | 22 +++++-------
 t/t0001-init.sh                    |  4 +--
 t/t0002-gitfile.sh                 |  2 +-
 t/t0027-auto-crlf.sh               | 14 +++++---
 t/t0060-path-utils.sh              | 57 ++++++++++++++++--------------
 t/t0100-previous.sh                |  4 +--
 t/t1401-symbolic-ref.sh            |  3 +-
 t/t1504-ceiling-dirs.sh            |  6 ++--
 t/t2005-checkout-index-symlinks.sh |  2 +-
 t/t3200-branch.sh                  |  9 ++---
 t/t3701-add-interactive.sh         |  9 +++--
 t/t4023-diff-rename-typechange.sh  | 12 +++----
 t/t4205-log-pretty-formats.sh      |  2 +-
 t/t5522-pull-symlink.sh            |  2 +-
 t/t5605-clone-local.sh             |  9 +++--
 t/t7402-submodule-rebase.sh        | 10 +++---
 t/t7504-commit-msg-hook.sh         |  2 +-
 t/t7516-commit-races.sh            |  3 +-
 t/t7600-merge.sh                   |  9 +++--
 t/t7810-grep.sh                    |  2 +-
 t/test-lib-functions.sh            | 18 ++++++++++
 23 files changed, 119 insertions(+), 94 deletions(-)

Range-diff against v1:
6:  259b4618fcb = 1:  7c9f8d2830f log tests: don't use "exit 1" outside a sub-shell
3:  cfc1abbf7e3 = 2:  345a667d5bb auto-crlf tests: check "git checkout" exit code
1:  f8a382841d5 = 3:  c5feef1c808 diff tests: fix ignored exit codes in t4023
4:  df1b674b8a7 ! 4:  c36060934a6 test-lib-functions: add and use test_cmp_cmd
    @@ Commit message
                 test_cmp_cmd --stdin <some-cmd> <expect
                 test_cmp_cmd --ignore-stderr "output" <some-cmd>
     
    -    By using this in t0060-path.sh we'll catch cases where "git" or
    -    "test-tool" errors (such as segfaults or abort()) were previously
    -    hidden, and we'd either pass the test, or fail in some subsequent
    -    assertion.
    +    By using this in we'll catch cases where "git" or "test-tool"
    +    errors (such as segfaults or abort()) were previously hidden, and we'd
    +    either pass the test, or fail in some subsequent assertion.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    + ## t/lib-submodule-update.sh ##
    +@@ t/lib-submodule-update.sh: test_git_directory_exists () {
    + 	if test -f sub1/.git
    + 	then
    + 		# does core.worktree point at the right place?
    +-		test "$(git -C .git/modules/$1 config core.worktree)" = "../../../$1"
    ++		test_cmp_cmd "../../../$1" git -C ".git/modules/$1" config core.worktree
    + 	fi
    + }
    + 
    +
    + ## t/t0001-init.sh ##
    +@@ t/t0001-init.sh: test_expect_success 'invalid default branch name' '
    + test_expect_success 'branch -m with the initial branch' '
    + 	git init rename-initial &&
    + 	git -C rename-initial branch -m renamed &&
    +-	test renamed = $(git -C rename-initial symbolic-ref --short HEAD) &&
    ++	test_cmp_cmd renamed git -C rename-initial symbolic-ref --short HEAD &&
    + 	git -C rename-initial branch -m renamed again &&
    +-	test again = $(git -C rename-initial symbolic-ref --short HEAD)
    ++	test_cmp_cmd again git -C rename-initial symbolic-ref --short HEAD
    + '
    + 
    + test_done
    +
    + ## t/t0002-gitfile.sh ##
    +@@ t/t0002-gitfile.sh: test_expect_success 'bad setup: invalid .git file path' '
    + 
    + test_expect_success 'final setup + check rev-parse --git-dir' '
    + 	echo "gitdir: $REAL" >.git &&
    +-	test "$REAL" = "$(git rev-parse --git-dir)"
    ++	test_cmp_cmd "$REAL" git rev-parse --git-dir
    + '
    + 
    + test_expect_success 'check hash-object' '
    +
      ## t/t0060-path-utils.sh ##
     @@ t/t0060-path-utils.sh: TEST_PASSES_SANITIZE_LEAK=true
      
    @@ t/t0060-path-utils.sh: TEST_PASSES_SANITIZE_LEAK=true
     -	test_expect_success $3 "normalize path: $1 => $2" \
     -	"test \"\$(test-tool path-utils normalize_path_copy '$1')\" = '$expected'"
     +	test_expect_success $3 "normalize path: $1 => $2" "
    -+		echo '$expected' >expect &&
    -+		test-tool path-utils normalize_path_copy '$1' >actual &&
    -+		test_cmp expect actual
    ++		test_cmp_cmd '$expected' test-tool path-utils normalize_path_copy '$1'
     +	"
      }
      
      relative_path() {
    + 	expected=$(test-tool path-utils print_path "$3")
    +-	test_expect_success $4 "relative path: $1 $2 => $3" \
    +-	"test \"\$(test-tool path-utils relative_path '$1' '$2')\" = '$expected'"
    ++	test_expect_success $4 "relative path: $1 $2 => $3" "
    ++		test_cmp_cmd '$expected' test-tool path-utils relative_path '$1' '$2'
    ++	"
    + }
    + 
    + test_submodule_relative_url() {
    + 	test_expect_success "test_submodule_relative_url: $1 $2 $3 => $4" "
    +-		actual=\$(test-tool submodule resolve-relative-url '$1' '$2' '$3') &&
    +-		test \"\$actual\" = '$4'
    ++		test_cmp_cmd '$4' test-tool submodule resolve-relative-url '$1' '$2' '$3'
    + 	"
    + }
    + 
    +@@ t/t0060-path-utils.sh: ancestor() {
    + 		expected=$(($expected-$rootslash+$rootoff))
    + 		;;
    + 	esac
    +-	test_expect_success $4 "longest ancestor: $1 $2 => $expected" \
    +-	"actual=\$(test-tool path-utils longest_ancestor_length '$1' '$2') &&
    +-	 test \"\$actual\" = '$expected'"
    ++	test_expect_success $4 "longest ancestor: $1 $2 => $expected" "
    ++		test_cmp_cmd '$expected' test-tool path-utils longest_ancestor_length '$1' '$2'
    ++	"
    + }
    + 
    + # Some absolute path tests should be skipped on Windows due to path mangling
     @@ t/t0060-path-utils.sh: ancestor D:/Users/me C:/ -1 MINGW
      ancestor //server/share/my-directory //server/share/ 14 MINGW
      
    @@ t/t0060-path-utils.sh: test_expect_success 'prefix_path rejects absolute path to
      
      relative_path /foo/a/b/c/	/foo/a/b/	c/
     
    + ## t/t0100-previous.sh ##
    +@@ t/t0100-previous.sh: test_expect_success 'branch -d @{-1}' '
    + 	test_commit A &&
    + 	git checkout -b junk &&
    + 	git checkout - &&
    +-	test "$(git symbolic-ref HEAD)" = refs/heads/main &&
    ++	test_cmp_cmd refs/heads/main git symbolic-ref HEAD &&
    + 	git branch -d @{-1} &&
    + 	test_must_fail git rev-parse --verify refs/heads/junk
    + '
    +@@ t/t0100-previous.sh: test_expect_success 'branch -d @{-12} when there is not enough switches yet' '
    + 	git reflog expire --expire=now &&
    + 	git checkout -b junk2 &&
    + 	git checkout - &&
    +-	test "$(git symbolic-ref HEAD)" = refs/heads/main &&
    ++	test_cmp_cmd refs/heads/main git symbolic-ref HEAD &&
    + 	test_must_fail git branch -d @{-12} &&
    + 	git rev-parse --verify refs/heads/main
    + '
    +
    + ## t/t1504-ceiling-dirs.sh ##
    +@@ t/t1504-ceiling-dirs.sh: TEST_PASSES_SANITIZE_LEAK=true
    + . ./test-lib.sh
    + 
    + test_prefix() {
    +-	test_expect_success "$1" \
    +-	"test '$2' = \"\$(git rev-parse --show-prefix)\""
    ++	local expect="$2" &&
    ++	test_expect_success "$1: git rev-parse --show-prefix is '$2'" '
    ++		test_cmp_cmd "$expect" git rev-parse --show-prefix
    ++	'
    + }
    + 
    + test_fail() {
    +
      ## t/test-lib-functions.sh ##
     @@ t/test-lib-functions.sh: test_cmp_rev () {
      	fi
2:  85c6ab40e91 ! 5:  f826a336c3d t/lib-patch-mode.sh: fix ignored "git" exit codes
    @@ Commit message
         t/lib-patch-mode.sh: fix ignored "git" exit codes
     
         Fix code added in b319ef70a94 (Add a small patch-mode testing library,
    -    2009-08-13) to use &&-chaining and test_cmp instead of interpolating
    -    "git" commands in a "test" statement.
    +    2009-08-13) to use &&-chaining and the newly added "test_cmp_cmd"
    +    instead of interpolating "git" commands in a "test" statement.
     
         This fixes cases where we'd have e.g. missed memory leaks under
         SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
    @@ t/lib-patch-mode.sh: set_and_save_state () {
     +	cat "$1" >actual &&
     +	test_cmp expect actual &&
     +
    -+	echo "$3" >expect
    -+	git show :"$1" >actual &&
    -+	test_cmp expect actual
    ++	test_cmp_cmd "$3" git show :"$1"
      }
      
      # verify_saved_state <path>
    @@ t/lib-patch-mode.sh: save_head () {
      
      verify_saved_head () {
     -	test "$(cat _head)" = "$(git rev-parse HEAD)"
    -+	cat _head >expect &&
    -+	git rev-parse HEAD >actual &&
    -+	test_cmp expect actual
    ++	test_cmp_cmd "$(cat _head)" git rev-parse HEAD
      }
5:  563666f9426 = 6:  5715ff7f0f7 merge tests: don't ignore "rev-parse" exit code in helper
-:  ----------- > 7:  d090478aa84 tests: use "test_cmp_cmd" instead of "test" in sub-shells
-:  ----------- > 8:  979a7f003f8 tests: use "test_cmp_cmd" in misc tests
-- 
2.39.0.rc1.980.g92d3d4579ad


^ permalink raw reply	[flat|nested] 83+ messages in thread

* [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell
  2022-12-02  0:06 ` [PATCH v2 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
@ 2022-12-02  0:06   ` Ævar Arnfjörð Bjarmason
  2022-12-02  1:02     ` Eric Sunshine
  2022-12-02  0:06   ` [PATCH v2 2/8] auto-crlf tests: check "git checkout" exit code Ævar Arnfjörð Bjarmason
                     ` (7 subsequent siblings)
  8 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02  0:06 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change an "exit 1" added in ac52d9410e5 (t4205: cover `git log
--reflog -z` blindspot, 2019-11-19) to use "return 1" instead, which
curiously was done in an adjacent test case added in the same commit.

Using "exit 1" outside a sub-shell will cause the test framework
itself to exit on failure, which isn't what we want to do here.

This issue was spotted with the in-flight
"GIT_TEST_PASSING_SANITIZE_LEAK=check" test mode[1]. This "git show"
invocation currently leaks memory, and we'd thus "exit 1". This change
was initially part of that topic[2] to demonstrate the correctness of
the "check" implementation.

1. https://lore.kernel.org/git/patch-07.10-0961df2ab6c-20220719T205710Z-avarab@gmail.com/
2. https://lore.kernel.org/git/patch-10.10-9cedf0cb0e2-20220719T205710Z-avarab@gmail.com/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t4205-log-pretty-formats.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index e448ef2928a..0404491d6ee 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -156,7 +156,7 @@ test_expect_success 'NUL termination with --reflog --pretty=oneline' '
 	for r in $revs
 	do
 		git show -s --pretty=oneline "$r" >raw &&
-		cat raw | lf_to_nul || exit 1
+		cat raw | lf_to_nul || return 1
 	done >expect &&
 	# the trailing NUL is already produced so we do not need to
 	# output another one
-- 
2.39.0.rc1.980.g92d3d4579ad


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v2 2/8] auto-crlf tests: check "git checkout" exit code
  2022-12-02  0:06 ` [PATCH v2 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
  2022-12-02  0:06   ` [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell Ævar Arnfjörð Bjarmason
@ 2022-12-02  0:06   ` Ævar Arnfjörð Bjarmason
  2022-12-02  1:02     ` René Scharfe
  2022-12-02  0:06   ` [PATCH v2 3/8] diff tests: fix ignored exit codes in t4023 Ævar Arnfjörð Bjarmason
                     ` (6 subsequent siblings)
  8 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02  0:06 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Don't hide the exit code from the "git checkout" we run to checkout
our attributes file.

This fixes cases where we'd have e.g. missed memory leaks under
SANITIZE=leak, this code doesn't leak (the relevant "git checkout"
leak has been fixed), but in a past version of git we'd continue past
this failure under SANITIZE=leak when these invocations had errored
out, even under "--immediate".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0027-auto-crlf.sh | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index a94ac1eae37..574344a99db 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -294,11 +294,17 @@ checkout_files () {
 	pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
 	for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
 	do
-		rm crlf_false_attr__$f.txt &&
-		if test -z "$ceol"; then
-			git checkout -- crlf_false_attr__$f.txt
+		if test -z "$ceol"
+		then
+			test_expect_success "setup $f checkout" '
+				rm crlf_false_attr__$f.txt &&
+				git checkout -- crlf_false_attr__$f.txt
+			'
 		else
-			git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
+			test_expect_success "setup $f checkout with core.eol=$ceol" '
+				rm crlf_false_attr__$f.txt &&
+				git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
+			'
 		fi
 	done
 
-- 
2.39.0.rc1.980.g92d3d4579ad


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v2 3/8] diff tests: fix ignored exit codes in t4023
  2022-12-02  0:06 ` [PATCH v2 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
  2022-12-02  0:06   ` [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell Ævar Arnfjörð Bjarmason
  2022-12-02  0:06   ` [PATCH v2 2/8] auto-crlf tests: check "git checkout" exit code Ævar Arnfjörð Bjarmason
@ 2022-12-02  0:06   ` Ævar Arnfjörð Bjarmason
  2022-12-02  2:02     ` Junio C Hamano
  2022-12-02  0:06   ` [PATCH v2 4/8] test-lib-functions: add and use test_cmp_cmd Ævar Arnfjörð Bjarmason
                     ` (5 subsequent siblings)
  8 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02  0:06 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change a "git diff-tree" command to be &&-chained so that we won't
ignore its exit code, see the ea05fd5fbf7 (Merge branch
'ab/keep-git-exit-codes-in-tests', 2022-03-16) topic for prior art.

This fixes code added in b45563a229f (rename: Break filepairs with
different types., 2007-11-30). Due to hiding the exit code we hid a
memory leak under SANITIZE=leak.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t4023-diff-rename-typechange.sh | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh
index 7cb99092938..25c31b0cb1b 100755
--- a/t/t4023-diff-rename-typechange.sh
+++ b/t/t4023-diff-rename-typechange.sh
@@ -52,8 +52,8 @@ test_expect_success setup '
 '
 
 test_expect_success 'cross renames to be detected for regular files' '
-
-	git diff-tree five six -r --name-status -B -M | sort >actual &&
+	git diff-tree five six -r --name-status -B -M >out &&
+	sort <out >actual &&
 	{
 		echo "R100	foo	bar" &&
 		echo "R100	bar	foo"
@@ -63,8 +63,8 @@ test_expect_success 'cross renames to be detected for regular files' '
 '
 
 test_expect_success 'cross renames to be detected for typechange' '
-
-	git diff-tree one two -r --name-status -B -M | sort >actual &&
+	git diff-tree one two -r --name-status -B -M >out &&
+	sort <out >actual &&
 	{
 		echo "R100	foo	bar" &&
 		echo "R100	bar	foo"
@@ -74,8 +74,8 @@ test_expect_success 'cross renames to be detected for typechange' '
 '
 
 test_expect_success 'moves and renames' '
-
-	git diff-tree three four -r --name-status -B -M | sort >actual &&
+	git diff-tree three four -r --name-status -B -M >out &&
+	sort <out >actual &&
 	{
 		# see -B -M (#6) in t4008
 		echo "C100	foo	bar" &&
-- 
2.39.0.rc1.980.g92d3d4579ad


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v2 4/8] test-lib-functions: add and use test_cmp_cmd
  2022-12-02  0:06 ` [PATCH v2 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                     ` (2 preceding siblings ...)
  2022-12-02  0:06   ` [PATCH v2 3/8] diff tests: fix ignored exit codes in t4023 Ævar Arnfjörð Bjarmason
@ 2022-12-02  0:06   ` Ævar Arnfjörð Bjarmason
  2022-12-02  1:30     ` René Scharfe
  2022-12-02  1:33     ` Eric Sunshine
  2022-12-02  0:06   ` [PATCH v2 5/8] t/lib-patch-mode.sh: fix ignored "git" exit codes Ævar Arnfjörð Bjarmason
                     ` (4 subsequent siblings)
  8 siblings, 2 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02  0:06 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Add a "test_cmp_cmd" helper for the common pattern discussed in the
documentation being added here to "t/test-lib-functions.sh".

This implementation leaves the door open for extending this helper
past its obvious limitations, such as:

	test_cmp_cmd "some" "lines" -- <some-cmd>
	test_cmp_cmd --stdin <some-cmd> <expect
	test_cmp_cmd --ignore-stderr "output" <some-cmd>

By using this in we'll catch cases where "git" or "test-tool"
errors (such as segfaults or abort()) were previously hidden, and we'd
either pass the test, or fail in some subsequent assertion.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-submodule-update.sh |  2 +-
 t/t0001-init.sh           |  4 +--
 t/t0002-gitfile.sh        |  2 +-
 t/t0060-path-utils.sh     | 57 ++++++++++++++++++++-------------------
 t/t0100-previous.sh       |  4 +--
 t/t1504-ceiling-dirs.sh   |  6 +++--
 t/test-lib-functions.sh   | 18 +++++++++++++
 7 files changed, 58 insertions(+), 35 deletions(-)

diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 2d31fcfda1f..d5d98714b4e 100644
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -189,7 +189,7 @@ test_git_directory_exists () {
 	if test -f sub1/.git
 	then
 		# does core.worktree point at the right place?
-		test "$(git -C .git/modules/$1 config core.worktree)" = "../../../$1"
+		test_cmp_cmd "../../../$1" git -C ".git/modules/$1" config core.worktree
 	fi
 }
 
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index d479303efa0..a3b902bcd8f 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -598,9 +598,9 @@ test_expect_success 'invalid default branch name' '
 test_expect_success 'branch -m with the initial branch' '
 	git init rename-initial &&
 	git -C rename-initial branch -m renamed &&
-	test renamed = $(git -C rename-initial symbolic-ref --short HEAD) &&
+	test_cmp_cmd renamed git -C rename-initial symbolic-ref --short HEAD &&
 	git -C rename-initial branch -m renamed again &&
-	test again = $(git -C rename-initial symbolic-ref --short HEAD)
+	test_cmp_cmd again git -C rename-initial symbolic-ref --short HEAD
 '
 
 test_done
diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh
index 26eaca095a2..aca847512c4 100755
--- a/t/t0002-gitfile.sh
+++ b/t/t0002-gitfile.sh
@@ -33,7 +33,7 @@ test_expect_success 'bad setup: invalid .git file path' '
 
 test_expect_success 'final setup + check rev-parse --git-dir' '
 	echo "gitdir: $REAL" >.git &&
-	test "$REAL" = "$(git rev-parse --git-dir)"
+	test_cmp_cmd "$REAL" git rev-parse --git-dir
 '
 
 test_expect_success 'check hash-object' '
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 68e29c904a6..c90d2e4d2b1 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -10,20 +10,21 @@ TEST_PASSES_SANITIZE_LEAK=true
 
 norm_path() {
 	expected=$(test-tool path-utils print_path "$2")
-	test_expect_success $3 "normalize path: $1 => $2" \
-	"test \"\$(test-tool path-utils normalize_path_copy '$1')\" = '$expected'"
+	test_expect_success $3 "normalize path: $1 => $2" "
+		test_cmp_cmd '$expected' test-tool path-utils normalize_path_copy '$1'
+	"
 }
 
 relative_path() {
 	expected=$(test-tool path-utils print_path "$3")
-	test_expect_success $4 "relative path: $1 $2 => $3" \
-	"test \"\$(test-tool path-utils relative_path '$1' '$2')\" = '$expected'"
+	test_expect_success $4 "relative path: $1 $2 => $3" "
+		test_cmp_cmd '$expected' test-tool path-utils relative_path '$1' '$2'
+	"
 }
 
 test_submodule_relative_url() {
 	test_expect_success "test_submodule_relative_url: $1 $2 $3 => $4" "
-		actual=\$(test-tool submodule resolve-relative-url '$1' '$2' '$3') &&
-		test \"\$actual\" = '$4'
+		test_cmp_cmd '$4' test-tool submodule resolve-relative-url '$1' '$2' '$3'
 	"
 }
 
@@ -64,9 +65,9 @@ ancestor() {
 		expected=$(($expected-$rootslash+$rootoff))
 		;;
 	esac
-	test_expect_success $4 "longest ancestor: $1 $2 => $expected" \
-	"actual=\$(test-tool path-utils longest_ancestor_length '$1' '$2') &&
-	 test \"\$actual\" = '$expected'"
+	test_expect_success $4 "longest ancestor: $1 $2 => $expected" "
+		test_cmp_cmd '$expected' test-tool path-utils longest_ancestor_length '$1' '$2'
+	"
 }
 
 # Some absolute path tests should be skipped on Windows due to path mangling
@@ -166,8 +167,10 @@ ancestor D:/Users/me C:/ -1 MINGW
 ancestor //server/share/my-directory //server/share/ 14 MINGW
 
 test_expect_success 'strip_path_suffix' '
-	test c:/msysgit = $(test-tool path-utils strip_path_suffix \
-		c:/msysgit/libexec//git-core libexec/git-core)
+	echo c:/msysgit >expect &&
+	test-tool path-utils strip_path_suffix \
+		c:/msysgit/libexec//git-core libexec/git-core >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'absolute path rejects the empty string' '
@@ -189,34 +192,34 @@ test_expect_success 'real path rejects the empty string' '
 
 test_expect_success POSIX 'real path works on absolute paths 1' '
 	nopath="hopefully-absent-path" &&
-	test "/" = "$(test-tool path-utils real_path "/")" &&
-	test "/$nopath" = "$(test-tool path-utils real_path "/$nopath")"
+	test_cmp_cmd / test-tool path-utils real_path "/" &&
+	test_cmp_cmd "/$nopath" test-tool path-utils real_path "/$nopath"
 '
 
 test_expect_success 'real path works on absolute paths 2' '
 	nopath="hopefully-absent-path" &&
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "$d")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "$d/$nopath")"
+	test_cmp_cmd "$d" test-tool path-utils real_path "$d" &&
+	test_cmp_cmd "$d/$nopath" test-tool path-utils real_path "$d/$nopath"
 '
 
 test_expect_success POSIX 'real path removes extra leading slashes' '
 	nopath="hopefully-absent-path" &&
-	test "/" = "$(test-tool path-utils real_path "///")" &&
-	test "/$nopath" = "$(test-tool path-utils real_path "///$nopath")" &&
+	test_cmp_cmd "/" test-tool path-utils real_path "///" &&
+	test_cmp_cmd "/$nopath" test-tool path-utils real_path "///$nopath" &&
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "//$d")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "//$d/$nopath")"
+	test_cmp_cmd "$d" test-tool path-utils real_path "//$d" &&
+	test_cmp_cmd "$d/$nopath" test-tool path-utils real_path "//$d/$nopath"
 '
 
 test_expect_success 'real path removes other extra slashes' '
 	nopath="hopefully-absent-path" &&
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "$d///")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "$d///$nopath")"
+	test_cmp_cmd "$d" test-tool path-utils real_path "$d///" &&
+	test_cmp_cmd "$d/$nopath" test-tool path-utils real_path "$d///$nopath"
 '
 
 test_expect_success SYMLINKS 'real path works on symlinks' '
@@ -227,19 +230,19 @@ test_expect_success SYMLINKS 'real path works on symlinks' '
 	mkdir third &&
 	dir="$(cd .git && pwd -P)" &&
 	dir2=third/../second/other/.git &&
-	test "$dir" = "$(test-tool path-utils real_path $dir2)" &&
+	test_cmp_cmd "$dir" test-tool path-utils real_path $dir2 &&
 	file="$dir"/index &&
-	test "$file" = "$(test-tool path-utils real_path $dir2/index)" &&
+	test_cmp_cmd "$file" test-tool path-utils real_path $dir2/index &&
 	basename=blub &&
-	test "$dir/$basename" = "$(cd .git && test-tool path-utils real_path "$basename")" &&
+	test_cmp_cmd "$dir/$basename" test-tool -C .git path-utils real_path "$basename" &&
 	ln -s ../first/file .git/syml &&
 	sym="$(cd first && pwd -P)"/file &&
-	test "$sym" = "$(test-tool path-utils real_path "$dir2/syml")"
+	test_cmp_cmd "$sym" test-tool path-utils real_path "$dir2/syml"
 '
 
 test_expect_success SYMLINKS 'prefix_path works with absolute paths to work tree symlinks' '
 	ln -s target symlink &&
-	test "$(test-tool path-utils prefix_path prefix "$(pwd)/symlink")" = "symlink"
+	test_cmp_cmd "symlink" test-tool path-utils prefix_path prefix "$(pwd)/symlink"
 '
 
 test_expect_success 'prefix_path works with only absolute path to work tree' '
@@ -255,7 +258,7 @@ test_expect_success 'prefix_path rejects absolute path to dir with same beginnin
 test_expect_success SYMLINKS 'prefix_path works with absolute path to a symlink to work tree having  same beginning as work tree' '
 	git init repo &&
 	ln -s repo repolink &&
-	test "a" = "$(cd repo && test-tool path-utils prefix_path prefix "$(pwd)/../repolink/a")"
+	test_cmp_cmd "a" test-tool -C repo path-utils prefix_path prefix "$(cd repo && pwd)/../repolink/a"
 '
 
 relative_path /foo/a/b/c/	/foo/a/b/	c/
diff --git a/t/t0100-previous.sh b/t/t0100-previous.sh
index a16cc3d2983..e315283cccd 100755
--- a/t/t0100-previous.sh
+++ b/t/t0100-previous.sh
@@ -12,7 +12,7 @@ test_expect_success 'branch -d @{-1}' '
 	test_commit A &&
 	git checkout -b junk &&
 	git checkout - &&
-	test "$(git symbolic-ref HEAD)" = refs/heads/main &&
+	test_cmp_cmd refs/heads/main git symbolic-ref HEAD &&
 	git branch -d @{-1} &&
 	test_must_fail git rev-parse --verify refs/heads/junk
 '
@@ -21,7 +21,7 @@ test_expect_success 'branch -d @{-12} when there is not enough switches yet' '
 	git reflog expire --expire=now &&
 	git checkout -b junk2 &&
 	git checkout - &&
-	test "$(git symbolic-ref HEAD)" = refs/heads/main &&
+	test_cmp_cmd refs/heads/main git symbolic-ref HEAD &&
 	test_must_fail git branch -d @{-12} &&
 	git rev-parse --verify refs/heads/main
 '
diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh
index 0fafcf9dde3..2c73869235d 100755
--- a/t/t1504-ceiling-dirs.sh
+++ b/t/t1504-ceiling-dirs.sh
@@ -6,8 +6,10 @@ TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_prefix() {
-	test_expect_success "$1" \
-	"test '$2' = \"\$(git rev-parse --show-prefix)\""
+	local expect="$2" &&
+	test_expect_success "$1: git rev-parse --show-prefix is '$2'" '
+		test_cmp_cmd "$expect" git rev-parse --show-prefix
+	'
 }
 
 test_fail() {
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 796093a7b32..0e8e0f808e3 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1274,6 +1274,24 @@ test_cmp_rev () {
 	fi
 }
 
+# test_cmp_cmd is a convenience helper for doing the more verbose:
+#
+#	echo something >expect &&
+#	<some-command-and-args> >actual &&
+#	test_cmp expect actual
+#
+# As:
+#
+#	test_cmp_cmd something <some-command-and-args>
+test_cmp_cmd () {
+	local expect="$1" &&
+	shift &&
+	printf "%s\n" "$expect" >expect &&
+	"$@" >actual 2>err &&
+	test_must_be_empty err
+	test_cmp expect actual
+}
+
 # Compare paths respecting core.ignoreCase
 test_cmp_fspath () {
 	if test "x$1" = "x$2"
-- 
2.39.0.rc1.980.g92d3d4579ad


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v2 5/8] t/lib-patch-mode.sh: fix ignored "git" exit codes
  2022-12-02  0:06 ` [PATCH v2 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                     ` (3 preceding siblings ...)
  2022-12-02  0:06   ` [PATCH v2 4/8] test-lib-functions: add and use test_cmp_cmd Ævar Arnfjörð Bjarmason
@ 2022-12-02  0:06   ` Ævar Arnfjörð Bjarmason
  2022-12-02  1:31     ` René Scharfe
  2022-12-02  0:06   ` [PATCH v2 6/8] merge tests: don't ignore "rev-parse" exit code in helper Ævar Arnfjörð Bjarmason
                     ` (3 subsequent siblings)
  8 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02  0:06 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Fix code added in b319ef70a94 (Add a small patch-mode testing library,
2009-08-13) to use &&-chaining and the newly added "test_cmp_cmd"
instead of interpolating "git" commands in a "test" statement.

This fixes cases where we'd have e.g. missed memory leaks under
SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
discovered it while looking at leaks in related code.

The "cat _head >expect" here is redundant, we could simply give
"_head" to "test_cmp", but let's be consistent in using the "expect"
and "actual" names for clarity.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-patch-mode.sh | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/t/lib-patch-mode.sh b/t/lib-patch-mode.sh
index cfd76bf987b..ae51f33a010 100644
--- a/t/lib-patch-mode.sh
+++ b/t/lib-patch-mode.sh
@@ -29,8 +29,11 @@ set_and_save_state () {
 
 # verify_state <path> <expected-worktree-content> <expected-index-content>
 verify_state () {
-	test "$(cat "$1")" = "$2" &&
-	test "$(git show :"$1")" = "$3"
+	echo "$2" >expect &&
+	cat "$1" >actual &&
+	test_cmp expect actual &&
+
+	test_cmp_cmd "$3" git show :"$1"
 }
 
 # verify_saved_state <path>
@@ -46,5 +49,5 @@ save_head () {
 }
 
 verify_saved_head () {
-	test "$(cat _head)" = "$(git rev-parse HEAD)"
+	test_cmp_cmd "$(cat _head)" git rev-parse HEAD
 }
-- 
2.39.0.rc1.980.g92d3d4579ad


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v2 6/8] merge tests: don't ignore "rev-parse" exit code in helper
  2022-12-02  0:06 ` [PATCH v2 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                     ` (4 preceding siblings ...)
  2022-12-02  0:06   ` [PATCH v2 5/8] t/lib-patch-mode.sh: fix ignored "git" exit codes Ævar Arnfjörð Bjarmason
@ 2022-12-02  0:06   ` Ævar Arnfjörð Bjarmason
  2022-12-02  1:41     ` René Scharfe
  2022-12-02  0:06   ` [PATCH v2 7/8] tests: use "test_cmp_cmd" instead of "test" in sub-shells Ævar Arnfjörð Bjarmason
                     ` (2 subsequent siblings)
  8 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02  0:06 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change the verify_mergeheads() helper the check the exit code of "git
rev-parse". The "$rest" variable added in 274a5c06d52 (merge: record
tag objects without peeling in MERGE_HEAD, 2011-11-07) wasn't being
used.

Such a thing is needed to support the .git/MERGE_HEAD format in
general, but in this case we have no such addition to the line. So
let's compare with "test_cmp" instead, we can always add back this
"$rest" parsing if it's needed in the future.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t7600-merge.sh | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 7c3f6ed9943..f5c4cbae9c8 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -102,12 +102,11 @@ verify_parents () {
 }
 
 verify_mergeheads () {
-	test_write_lines "$@" >mergehead.expected &&
-	while read sha1 rest
+	for rev in "$@"
 	do
-		git rev-parse $sha1
-	done <.git/MERGE_HEAD >mergehead.actual &&
-	test_cmp mergehead.expected mergehead.actual
+		git rev-parse $rev || return 1
+	done >mergehead.expected &&
+	test_cmp mergehead.expected .git/MERGE_HEAD
 }
 
 verify_no_mergehead () {
-- 
2.39.0.rc1.980.g92d3d4579ad


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v2 7/8] tests: use "test_cmp_cmd" instead of "test" in sub-shells
  2022-12-02  0:06 ` [PATCH v2 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                     ` (5 preceding siblings ...)
  2022-12-02  0:06   ` [PATCH v2 6/8] merge tests: don't ignore "rev-parse" exit code in helper Ævar Arnfjörð Bjarmason
@ 2022-12-02  0:06   ` Ævar Arnfjörð Bjarmason
  2022-12-02  0:06   ` [PATCH v2 8/8] tests: use "test_cmp_cmd" in misc tests Ævar Arnfjörð Bjarmason
  2022-12-02 11:52   ` [PATCH v3 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
  8 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02  0:06 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Convert a few cases where we were using "test" inside a sub-shell, and
were losing the exit code of "git".

In the case of "t3200-branch.sh" some adjacent code outside of a
sub-shell that was losing the exit code is also being converted, as
it's within the same hunk.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-httpd.sh              |  3 +--
 t/lib-submodule-update.sh   | 20 +++++++-------------
 t/t3200-branch.sh           |  9 +++------
 t/t5605-clone-local.sh      |  9 ++++-----
 t/t7402-submodule-rebase.sh |  6 +++---
 5 files changed, 18 insertions(+), 29 deletions(-)

diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index 608949ea80b..082496d6535 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -217,8 +217,7 @@ test_http_push_nonff () {
 		git commit -a -m path2 --amend &&
 
 		test_must_fail git push -v origin >output 2>&1 &&
-		(cd "$REMOTE_REPO" &&
-		 test $HEAD = $(git rev-parse --verify HEAD))
+		test_cmp_cmd "$HEAD" git -C "$REMOTE_REPO" rev-parse --verify HEAD
 	'
 
 	test_expect_success 'non-fast-forward push show ref status' '
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index d5d98714b4e..207fab77bd3 100644
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -168,20 +168,14 @@ replace_gitfile_with_git_dir () {
 # Note that this only supports submodules at the root level of the
 # superproject, with the default name, i.e. same as its path.
 test_git_directory_is_unchanged () {
-	(
-		cd ".git/modules/$1" &&
-		# does core.worktree point at the right place?
-		test "$(git config core.worktree)" = "../../../$1" &&
-		# remove it temporarily before comparing, as
-		# "$1/.git/config" lacks it...
-		git config --unset core.worktree
-	) &&
+	# does core.worktree point at the right place?
+	test_cmp_cmd "../../../$1" git -C ".git/modules/$1" config core.worktree
+	# remove it temporarily before comparing, as
+	# "$1/.git/config" lacks it...
+	git -C ".git/modules/$1" config --unset core.worktree &&
 	diff -r ".git/modules/$1" "$1/.git" &&
-	(
-		# ... and then restore.
-		cd ".git/modules/$1" &&
-		git config core.worktree "../../../$1"
-	)
+	# ... and then restore.
+	git -C ".git/modules/$1" config core.worktree "../../../$1"
 }
 
 test_git_directory_exists () {
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 5a169b68d6a..c31036b49be 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -242,12 +242,9 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
 test_expect_success 'git branch -M baz bam should succeed within a worktree in which baz is checked out' '
 	git checkout -b baz &&
 	git worktree add -f bazdir baz &&
-	(
-		cd bazdir &&
-		git branch -M baz bam &&
-		test $(git rev-parse --abbrev-ref HEAD) = bam
-	) &&
-	test $(git rev-parse --abbrev-ref HEAD) = bam &&
+	git -C "$bazdir" branch -M baz bam &&
+	test_cmp_cmd "bam" git -C "$bazdir" rev-parse --abbrev-ref HEAD &&
+	test_cmp_cmd "bam" git rev-parse --abbrev-ref HEAD &&
 	rm -r bazdir &&
 	git worktree prune
 '
diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh
index 38b850c10ef..55bda2c0aa9 100755
--- a/t/t5605-clone-local.sh
+++ b/t/t5605-clone-local.sh
@@ -15,8 +15,8 @@ test_expect_success 'preparing origin repository' '
 	: >file && git add . && git commit -m1 &&
 	git clone --bare . a.git &&
 	git clone --bare . x &&
-	test "$(cd a.git && git config --bool core.bare)" = true &&
-	test "$(cd x && git config --bool core.bare)" = true &&
+	test_cmp_cmd true git -C a.git config --bool core.bare &&
+	test_cmp_cmd true git -C x config --bool core.bare &&
 	git bundle create b1.bundle --all &&
 	git bundle create b2.bundle main &&
 	mkdir dir &&
@@ -28,9 +28,8 @@ test_expect_success 'preparing origin repository' '
 
 test_expect_success 'local clone without .git suffix' '
 	git clone -l -s a b &&
-	(cd b &&
-	test "$(git config --bool core.bare)" = false &&
-	git fetch)
+	test_cmp_cmd false git -C b config --bool core.bare &&
+	git -C b fetch
 '
 
 test_expect_success 'local clone with .git suffix' '
diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh
index ebeca12a711..277bb8ae520 100755
--- a/t/t7402-submodule-rebase.sh
+++ b/t/t7402-submodule-rebase.sh
@@ -82,11 +82,11 @@ test_expect_success 'stash with a dirty submodule' '
 	CURRENT=$(cd submodule && git rev-parse HEAD) &&
 	git stash &&
 	test new != $(cat file) &&
-	test submodule = $(git diff --name-only) &&
-	test $CURRENT = $(cd submodule && git rev-parse HEAD) &&
+	test_cmp_cmd submodule git diff --name-only &&
+	test_cmp_cmd "$CURRENT" git -C submodule rev-parse HEAD &&
 	git stash apply &&
 	test new = $(cat file) &&
-	test $CURRENT = $(cd submodule && git rev-parse HEAD)
+	test_cmp_cmd "$CURRENT" git -C submodule rev-parse HEAD
 
 '
 
-- 
2.39.0.rc1.980.g92d3d4579ad


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v2 8/8] tests: use "test_cmp_cmd" in misc tests
  2022-12-02  0:06 ` [PATCH v2 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                     ` (6 preceding siblings ...)
  2022-12-02  0:06   ` [PATCH v2 7/8] tests: use "test_cmp_cmd" instead of "test" in sub-shells Ævar Arnfjörð Bjarmason
@ 2022-12-02  0:06   ` Ævar Arnfjörð Bjarmason
  2022-12-02  2:19     ` Junio C Hamano
  2022-12-02 11:52   ` [PATCH v3 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
  8 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02  0:06 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Ævar Arnfjörð Bjarmason

Change a few miscellaneous tests to use "test_cmp_cmd" to avoid losing
the exit code of "git".

There's many offenders left that match patterns like:

	/test .*\$\((test-tool|git)/

What these all have in common is that they were the rare odd cases out
in test files that were otherwise consistently checking the exit code.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1401-symbolic-ref.sh            | 3 ++-
 t/t2005-checkout-index-symlinks.sh | 2 +-
 t/t3701-add-interactive.sh         | 9 ++++++---
 t/t5522-pull-symlink.sh            | 2 +-
 t/t7402-submodule-rebase.sh        | 4 ++--
 t/t7504-commit-msg-hook.sh         | 2 +-
 t/t7516-commit-races.sh            | 3 ++-
 t/t7810-grep.sh                    | 2 +-
 8 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh
index d708acdb819..5e36899d207 100755
--- a/t/t1401-symbolic-ref.sh
+++ b/t/t1401-symbolic-ref.sh
@@ -33,7 +33,8 @@ test_expect_success 'symbolic-ref refuses non-ref for HEAD' '
 reset_to_sane
 
 test_expect_success 'symbolic-ref refuses bare sha1' '
-	test_must_fail git symbolic-ref HEAD $(git rev-parse HEAD)
+	rev=$(git rev-parse HEAD) &&
+	test_must_fail git symbolic-ref HEAD "$rev"
 '
 
 reset_to_sane
diff --git a/t/t2005-checkout-index-symlinks.sh b/t/t2005-checkout-index-symlinks.sh
index 112682a45a1..aee80d39221 100755
--- a/t/t2005-checkout-index-symlinks.sh
+++ b/t/t2005-checkout-index-symlinks.sh
@@ -24,6 +24,6 @@ test -f symlink'
 
 test_expect_success \
 'the file must be the blob we added during the setup' '
-test "$(git hash-object -t blob symlink)" = $l'
+test_cmp_cmd "$l" git hash-object -t blob symlink'
 
 test_done
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 5841f280fb2..3e59ffd18a0 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -296,9 +296,12 @@ test_expect_success FILEMODE 'stage mode and hunk' '
 	echo content >>file &&
 	chmod +x file &&
 	printf "y\\ny\\n" | git add -p &&
-	git diff --cached file | grep "new mode" &&
-	git diff --cached file | grep "+content" &&
-	test -z "$(git diff file)"
+	git diff --cached file >out &&
+	grep "new mode" <out &&
+	git diff --cached file >out &&
+	grep "+content" <out &&
+	git diff file >out &&
+	test_must_be_empty out
 '
 
 # end of tests disabled when filemode is not usable
diff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh
index bcff460d0a2..b36dd40e34e 100755
--- a/t/t5522-pull-symlink.sh
+++ b/t/t5522-pull-symlink.sh
@@ -78,7 +78,7 @@ test_expect_success SYMLINKS 'pushing from symlinked subdir' '
 		git commit -m push ./file &&
 		git push
 	) &&
-	test push = $(git show HEAD:subdir/file)
+	test_cmp_cmd push git show HEAD:subdir/file
 '
 
 test_done
diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh
index 277bb8ae520..b27d8da69ee 100755
--- a/t/t7402-submodule-rebase.sh
+++ b/t/t7402-submodule-rebase.sh
@@ -55,11 +55,11 @@ chmod a+x fake-editor.sh
 
 test_expect_success 'interactive rebase with a dirty submodule' '
 
-	test submodule = $(git diff --name-only) &&
+	test_cmp_cmd submodule git diff --name-only &&
 	HEAD=$(git rev-parse HEAD) &&
 	GIT_EDITOR="\"$(pwd)/fake-editor.sh\"" EDITOR_TEXT="pick $HEAD" \
 		git rebase -i HEAD^ &&
-	test submodule = $(git diff --name-only)
+	test_cmp_cmd submodule git diff --name-only
 
 '
 
diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh
index a39de8c1126..2b94237f9d1 100755
--- a/t/t7504-commit-msg-hook.sh
+++ b/t/t7504-commit-msg-hook.sh
@@ -101,7 +101,7 @@ test_expect_success 'setup: commit-msg hook that always fails' '
 '
 
 commit_msg_is () {
-	test "$(git log --pretty=format:%s%b -1)" = "$1"
+	test_cmp_cmd "$1" git log --pretty=tformat:%s%b -1
 }
 
 test_expect_success 'with failing hook' '
diff --git a/t/t7516-commit-races.sh b/t/t7516-commit-races.sh
index f2ce14e9071..2d38a16480e 100755
--- a/t/t7516-commit-races.sh
+++ b/t/t7516-commit-races.sh
@@ -10,7 +10,8 @@ test_expect_success 'race to create orphan commit' '
 	test_must_fail env EDITOR=./hare-editor git commit --allow-empty -m tortoise -e &&
 	git show -s --pretty=format:%s >subject &&
 	grep hare subject &&
-	test -z "$(git show -s --pretty=format:%P)"
+	git show -s --pretty=format:%P >out &&
+	test_must_be_empty out
 '
 
 test_expect_success 'race to create non-orphan commit' '
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 8eded6ab274..232b041b0cf 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -1001,7 +1001,7 @@ test_expect_success 'log --committer does not search in timestamp' '
 test_expect_success 'grep with CE_VALID file' '
 	git update-index --assume-unchanged t/t &&
 	rm t/t &&
-	test "$(git grep test)" = "t/t:test" &&
+	test_cmp_cmd "t/t:test" git grep test &&
 	git update-index --no-assume-unchanged t/t &&
 	git checkout t/t
 '
-- 
2.39.0.rc1.980.g92d3d4579ad


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell
  2022-12-02  0:06   ` [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell Ævar Arnfjörð Bjarmason
@ 2022-12-02  1:02     ` Eric Sunshine
  2022-12-02  1:48       ` Junio C Hamano
  2022-12-02  3:24       ` Junio C Hamano
  0 siblings, 2 replies; 83+ messages in thread
From: Eric Sunshine @ 2022-12-02  1:02 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, René Scharfe

On Thu, Dec 1, 2022 at 7:07 PM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
> Change an "exit 1" added in ac52d9410e5 (t4205: cover `git log
> --reflog -z` blindspot, 2019-11-19) to use "return 1" instead, which
> curiously was done in an adjacent test case added in the same commit.
>
> Using "exit 1" outside a sub-shell will cause the test framework
> itself to exit on failure, which isn't what we want to do here.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
> diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
> @@ -156,7 +156,7 @@ test_expect_success 'NUL termination with --reflog --pretty=oneline' '
>         for r in $revs
>         do
>                 git show -s --pretty=oneline "$r" >raw &&
> -               cat raw | lf_to_nul || exit 1
> +               cat raw | lf_to_nul || return 1
>         done >expect &&

Using `return 1` here is "obviously correct" since this code is not
inside a subshell. Furthermore, the exit code of the for-loop itself
is not being lost down a pipe, so `return 1` is indeed an appropriate
way to signal failure. Good.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 2/8] auto-crlf tests: check "git checkout" exit code
  2022-12-02  0:06   ` [PATCH v2 2/8] auto-crlf tests: check "git checkout" exit code Ævar Arnfjörð Bjarmason
@ 2022-12-02  1:02     ` René Scharfe
  2022-12-02  1:10       ` Eric Sunshine
  2022-12-02  5:59       ` Torsten Bögershausen
  0 siblings, 2 replies; 83+ messages in thread
From: René Scharfe @ 2022-12-02  1:02 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git; +Cc: Junio C Hamano, Eric Sunshine

Am 02.12.2022 um 01:06 schrieb Ævar Arnfjörð Bjarmason:
> Don't hide the exit code from the "git checkout" we run to checkout
> our attributes file.
>
> This fixes cases where we'd have e.g. missed memory leaks under
> SANITIZE=leak, this code doesn't leak (the relevant "git checkout"
> leak has been fixed), but in a past version of git we'd continue past
> this failure under SANITIZE=leak when these invocations had errored
> out, even under "--immediate".
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t0027-auto-crlf.sh | 14 ++++++++++----
>  1 file changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
> index a94ac1eae37..574344a99db 100755
> --- a/t/t0027-auto-crlf.sh
> +++ b/t/t0027-auto-crlf.sh
> @@ -294,11 +294,17 @@ checkout_files () {
>  	pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
>  	for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
>  	do
> -		rm crlf_false_attr__$f.txt &&
> -		if test -z "$ceol"; then
> -			git checkout -- crlf_false_attr__$f.txt
> +		if test -z "$ceol"
> +		then
> +			test_expect_success "setup $f checkout" '
> +				rm crlf_false_attr__$f.txt &&
> +				git checkout -- crlf_false_attr__$f.txt
> +			'
>  		else
> -			git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
> +			test_expect_success "setup $f checkout with core.eol=$ceol" '
> +				rm crlf_false_attr__$f.txt &&
> +				git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
> +			'

That adds five test_expect_success calls.  Wouldn't one suffice, for the
whole for loop, and a "|| return 1"?

One line above the context there's a "git config" call that should also
be covered, right?

Side note: The checkout commands only differ in their -c parameter.
They could be unified like this, which might simplify handling their
return code:

	git ${ceol:+-c core.eol=$ceol} checkout -- crlf_false_attr__$f.txt

>  		fi
>  	done
>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 2/8] auto-crlf tests: check "git checkout" exit code
  2022-12-02  1:02     ` René Scharfe
@ 2022-12-02  1:10       ` Eric Sunshine
  2022-12-02  5:59       ` Torsten Bögershausen
  1 sibling, 0 replies; 83+ messages in thread
From: Eric Sunshine @ 2022-12-02  1:10 UTC (permalink / raw)
  To: René Scharfe
  Cc: Ævar Arnfjörð Bjarmason, git, Junio C Hamano

On Thu, Dec 1, 2022 at 8:02 PM René Scharfe <l.s.r@web.de> wrote:
> Am 02.12.2022 um 01:06 schrieb Ævar Arnfjörð Bjarmason:
> > Don't hide the exit code from the "git checkout" we run to checkout
> > our attributes file.
> > @@ -294,11 +294,17 @@ checkout_files () {
> >       pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
> >       for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
> >       do
> > -             rm crlf_false_attr__$f.txt &&
> > -             if test -z "$ceol"; then
> > -                     git checkout -- crlf_false_attr__$f.txt
> > +             if test -z "$ceol"
> > +             then
> > +                     test_expect_success "setup $f checkout" '
> > +                             rm crlf_false_attr__$f.txt &&
> > +                             git checkout -- crlf_false_attr__$f.txt
> > +                     '
> >               else
> > -                     git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
> > +                     test_expect_success "setup $f checkout with core.eol=$ceol" '
> > +                             rm crlf_false_attr__$f.txt &&
> > +                             git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
> > +                     '
>
> That adds five test_expect_success calls.  Wouldn't one suffice, for the
> whole for loop, and a "|| return 1"?

Seems like a reasonable idea.

> One line above the context there's a "git config" call that should also
> be covered, right?

Also, the call to create_gitattributes() just above that line is in
the function's &&-chain, which implies that it too should be covered.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 4/8] test-lib-functions: add and use test_cmp_cmd
  2022-12-02  0:06   ` [PATCH v2 4/8] test-lib-functions: add and use test_cmp_cmd Ævar Arnfjörð Bjarmason
@ 2022-12-02  1:30     ` René Scharfe
  2022-12-02  1:33     ` Eric Sunshine
  1 sibling, 0 replies; 83+ messages in thread
From: René Scharfe @ 2022-12-02  1:30 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git; +Cc: Junio C Hamano, Eric Sunshine

Am 02.12.2022 um 01:06 schrieb Ævar Arnfjörð Bjarmason:
> Add a "test_cmp_cmd" helper for the common pattern discussed in the
> documentation being added here to "t/test-lib-functions.sh".
>
> This implementation leaves the door open for extending this helper
> past its obvious limitations, such as:
>
> 	test_cmp_cmd "some" "lines" -- <some-cmd>
> 	test_cmp_cmd --stdin <some-cmd> <expect
> 	test_cmp_cmd --ignore-stderr "output" <some-cmd>
>
> By using this in we'll catch cases where "git" or "test-tool"
> errors (such as segfaults or abort()) were previously hidden, and we'd
> either pass the test, or fail in some subsequent assertion.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---

> diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> index 796093a7b32..0e8e0f808e3 100644
> --- a/t/test-lib-functions.sh
> +++ b/t/test-lib-functions.sh
> @@ -1274,6 +1274,24 @@ test_cmp_rev () {
>  	fi
>  }
>
> +# test_cmp_cmd is a convenience helper for doing the more verbose:
> +#
> +#	echo something >expect &&
> +#	<some-command-and-args> >actual &&
> +#	test_cmp expect actual
> +#
> +# As:
> +#
> +#	test_cmp_cmd something <some-command-and-args>
> +test_cmp_cmd () {
> +	local expect="$1" &&
> +	shift &&
> +	printf "%s\n" "$expect" >expect &&
> +	"$@" >actual 2>err &&
> +	test_must_be_empty err
> +	test_cmp expect actual

err, expect and actual are common filenames used in tests.
Clobbering them might be surprising.  Perhaps at least add some
prefix (e.g. name them test_cmp_cmd_expect etc.), like other
functions in that script do, to avoid collisions?

> +}
> +
>  # Compare paths respecting core.ignoreCase
>  test_cmp_fspath () {
>  	if test "x$1" = "x$2"

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 5/8] t/lib-patch-mode.sh: fix ignored "git" exit codes
  2022-12-02  0:06   ` [PATCH v2 5/8] t/lib-patch-mode.sh: fix ignored "git" exit codes Ævar Arnfjörð Bjarmason
@ 2022-12-02  1:31     ` René Scharfe
  0 siblings, 0 replies; 83+ messages in thread
From: René Scharfe @ 2022-12-02  1:31 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git; +Cc: Junio C Hamano, Eric Sunshine

Am 02.12.2022 um 01:06 schrieb Ævar Arnfjörð Bjarmason:
> Fix code added in b319ef70a94 (Add a small patch-mode testing library,
> 2009-08-13) to use &&-chaining and the newly added "test_cmp_cmd"
> instead of interpolating "git" commands in a "test" statement.
>
> This fixes cases where we'd have e.g. missed memory leaks under
> SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
> discovered it while looking at leaks in related code.
>
> The "cat _head >expect" here is redundant, we could simply give
> "_head" to "test_cmp", but let's be consistent in using the "expect"
> and "actual" names for clarity.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/lib-patch-mode.sh | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/t/lib-patch-mode.sh b/t/lib-patch-mode.sh
> index cfd76bf987b..ae51f33a010 100644
> --- a/t/lib-patch-mode.sh
> +++ b/t/lib-patch-mode.sh
> @@ -29,8 +29,11 @@ set_and_save_state () {
>
>  # verify_state <path> <expected-worktree-content> <expected-index-content>
>  verify_state () {
> -	test "$(cat "$1")" = "$2" &&
> -	test "$(git show :"$1")" = "$3"
> +	echo "$2" >expect &&
> +	cat "$1" >actual &&
> +	test_cmp expect actual &&

Hmm, I'd have expected this oneliner instead, matching the conversion of
the second command:

	test_cmp_cmd "$2" cat "$1" &&

cat is not a git command, though, so the extra checks of test_cmp_cmd
are unnecessary.  But how about avoiding its useless use then?

	echo "$2" >expect &&
	test_cmp expect "$1" &&

> +
> +	test_cmp_cmd "$3" git show :"$1"
>  }
>
>  # verify_saved_state <path>
> @@ -46,5 +49,5 @@ save_head () {
>  }
>
>  verify_saved_head () {
> -	test "$(cat _head)" = "$(git rev-parse HEAD)"
> +	test_cmp_cmd "$(cat _head)" git rev-parse HEAD
>  }

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 4/8] test-lib-functions: add and use test_cmp_cmd
  2022-12-02  0:06   ` [PATCH v2 4/8] test-lib-functions: add and use test_cmp_cmd Ævar Arnfjörð Bjarmason
  2022-12-02  1:30     ` René Scharfe
@ 2022-12-02  1:33     ` Eric Sunshine
  2022-12-02  1:45       ` Eric Sunshine
  1 sibling, 1 reply; 83+ messages in thread
From: Eric Sunshine @ 2022-12-02  1:33 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, René Scharfe

On Thu, Dec 1, 2022 at 7:07 PM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
> Add a "test_cmp_cmd" helper for the common pattern discussed in the
> documentation being added here to "t/test-lib-functions.sh".

I'm somewhat "meh" on this, at least as it's sold here. Perhaps if it
was sold as producing better diagnostic report for:

    test "$something" = "$(git blah)"

which covers many of the "fixes" in this patch then I'd be less jaded...

> By using this in we'll catch cases where "git" or "test-tool"
> errors (such as segfaults or abort()) were previously hidden, and we'd
> either pass the test, or fail in some subsequent assertion.

...which, I suppose, may be what this paragraph is saying, but it's
not immediately obvious.

Minor subjective stuff aside...

> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
> diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> +# test_cmp_cmd is a convenience helper for doing the more verbose:
> +#
> +#      echo something >expect &&
> +#      <some-command-and-args> >actual &&
> +#      test_cmp expect actual
> +#
> +# As:
> +#
> +#      test_cmp_cmd something <some-command-and-args>
> +test_cmp_cmd () {
> +       local expect="$1" &&
> +       shift &&
> +       printf "%s\n" "$expect" >expect &&
> +       "$@" >actual 2>err &&
> +       test_must_be_empty err
> +       test_cmp expect actual
> +}

I do find it concerning that this clobbers 'actual', 'expect', and
'err', which are common enough names. I'd suggest using names unique
to this function (perhaps 'test_cmp_cmd.actual',
'test_cmp_cmd.expect', etc.).

I think you also need to document the fact that it expects stderr
output to be empty.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 6/8] merge tests: don't ignore "rev-parse" exit code in helper
  2022-12-02  0:06   ` [PATCH v2 6/8] merge tests: don't ignore "rev-parse" exit code in helper Ævar Arnfjörð Bjarmason
@ 2022-12-02  1:41     ` René Scharfe
  0 siblings, 0 replies; 83+ messages in thread
From: René Scharfe @ 2022-12-02  1:41 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git; +Cc: Junio C Hamano, Eric Sunshine

Am 02.12.2022 um 01:06 schrieb Ævar Arnfjörð Bjarmason:
> Change the verify_mergeheads() helper the check the exit code of "git
> rev-parse". The "$rest" variable added in 274a5c06d52 (merge: record
> tag objects without peeling in MERGE_HEAD, 2011-11-07) wasn't being
> used.
>
> Such a thing is needed to support the .git/MERGE_HEAD format in
> general, but in this case we have no such addition to the line. So
> let's compare with "test_cmp" instead, we can always add back this
> "$rest" parsing if it's needed in the future.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t7600-merge.sh | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
> index 7c3f6ed9943..f5c4cbae9c8 100755
> --- a/t/t7600-merge.sh
> +++ b/t/t7600-merge.sh
> @@ -102,12 +102,11 @@ verify_parents () {
>  }
>
>  verify_mergeheads () {
> -	test_write_lines "$@" >mergehead.expected &&
> -	while read sha1 rest
> +	for rev in "$@"
>  	do
> -		git rev-parse $sha1
> -	done <.git/MERGE_HEAD >mergehead.actual &&
> -	test_cmp mergehead.expected mergehead.actual
> +		git rev-parse $rev || return 1
> +	done >mergehead.expected &&
> +	test_cmp mergehead.expected .git/MERGE_HEAD

Why all these changes and not just add "|| return 1"?

>  }
>
>  verify_no_mergehead () {

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 4/8] test-lib-functions: add and use test_cmp_cmd
  2022-12-02  1:33     ` Eric Sunshine
@ 2022-12-02  1:45       ` Eric Sunshine
  2022-12-02  1:52         ` Eric Sunshine
  2022-12-02  3:41         ` Junio C Hamano
  0 siblings, 2 replies; 83+ messages in thread
From: Eric Sunshine @ 2022-12-02  1:45 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, René Scharfe

On Thu, Dec 1, 2022 at 8:33 PM Eric Sunshine <sunshine@sunshineco.com> wrote:
> On Thu, Dec 1, 2022 at 7:07 PM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
> > diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> > +# test_cmp_cmd is a convenience helper for doing the more verbose:
> > +#
> > +#      echo something >expect &&
> > +#      <some-command-and-args> >actual &&
> > +#      test_cmp expect actual
> > +#
> > +# As:
> > +#
> > +#      test_cmp_cmd something <some-command-and-args>
> > +test_cmp_cmd () {
> > +       local expect="$1" &&
> > +       shift &&
> > +       printf "%s\n" "$expect" >expect &&
> > +       "$@" >actual 2>err &&
> > +       test_must_be_empty err
> > +       test_cmp expect actual
> > +}
>
> I think you also need to document the fact that it expects stderr
> output to be empty.

That said, the behavior of expecting stderr output to be empty seems
like a potentially bad default since it won't play well with commands
which send their "chatty" output to stderr.

Another reason I'm "meh" about this function is that it seems too
narrowly focussed, insisting that the "expect" argument is expressed
as a one-liner. (Yes, I know that that is not a hard limitation; a
caller can pass in a multiline string, but still...) Maybe I'd be less
jaded if it accepted "expect" on its stdin. But, even that doesn't
seem to buy much. The vast majority of cases where you've converted:

    test "$dir" = "$(test-tool path-utils real_path $dir2)" &&

to:

    test_cmp_cmd "$dir" test-tool path-utils real_path $dir2 &&

could just have easily become:

    echo "$dir" >expect &&
    test_cmp test-tool path-utils real_path $dir2 &&

which isn't bad at all, even if it is one line longer, and it is
idiomatic in this test suite.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell
  2022-12-02  1:02     ` Eric Sunshine
@ 2022-12-02  1:48       ` Junio C Hamano
  2022-12-02  2:45         ` Ævar Arnfjörð Bjarmason
  2022-12-02  3:24       ` Junio C Hamano
  1 sibling, 1 reply; 83+ messages in thread
From: Junio C Hamano @ 2022-12-02  1:48 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Ævar Arnfjörð Bjarmason, git, René Scharfe

Eric Sunshine <sunshine@sunshineco.com> writes:

>>                 git show -s --pretty=oneline "$r" >raw &&
>> -               cat raw | lf_to_nul || exit 1
>> +               cat raw | lf_to_nul || return 1
>>         done >expect &&
>
> Using `return 1` here is "obviously correct" since this code is not
> inside a subshell. Furthermore, the exit code of the for-loop itself
> is not being lost down a pipe, so `return 1` is indeed an appropriate
> way to signal failure. Good.

"return 1" is obvious and safe correction.  I have to wonder if
test_expect_success can be taught to be smarter to intercept "exit"
so we do not have to bo so careful, but that would be a much more
involved change to the lower-level of test framework.


^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 4/8] test-lib-functions: add and use test_cmp_cmd
  2022-12-02  1:45       ` Eric Sunshine
@ 2022-12-02  1:52         ` Eric Sunshine
  2022-12-02  3:41         ` Junio C Hamano
  1 sibling, 0 replies; 83+ messages in thread
From: Eric Sunshine @ 2022-12-02  1:52 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, René Scharfe

On Thu, Dec 1, 2022 at 8:45 PM Eric Sunshine <sunshine@sunshineco.com> wrote:
> But, even that doesn't
> seem to buy much. The vast majority of cases where you've converted:
>
>     test "$dir" = "$(test-tool path-utils real_path $dir2)" &&
>
> to:
>
>     test_cmp_cmd "$dir" test-tool path-utils real_path $dir2 &&
>
> could just have easily become:
>
>     echo "$dir" >expect &&
>     test_cmp test-tool path-utils real_path $dir2 &&
>
> which isn't bad at all, even if it is one line longer, and it is
> idiomatic in this test suite.

I can't count. Of course, I meant:

     echo "$dir" >expect &&
     test-tool path-utils real_path $dir2 >actual &&
     test_cmp expect actual &&

which is two extra lines.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 3/8] diff tests: fix ignored exit codes in t4023
  2022-12-02  0:06   ` [PATCH v2 3/8] diff tests: fix ignored exit codes in t4023 Ævar Arnfjörð Bjarmason
@ 2022-12-02  2:02     ` Junio C Hamano
  0 siblings, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-02  2:02 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, René Scharfe, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change a "git diff-tree" command to be &&-chained so that we won't
> ignore its exit code, see the ea05fd5fbf7 (Merge branch
> 'ab/keep-git-exit-codes-in-tests', 2022-03-16) topic for prior art.
>
> This fixes code added in b45563a229f (rename: Break filepairs with
> different types., 2007-11-30). Due to hiding the exit code we hid a
> memory leak under SANITIZE=leak.

Thanks.

The changes all make sense and obviously correct.  The ancient style
to have a blank line before the first statement in the test body is
also gone, which is a good thing.


> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t4023-diff-rename-typechange.sh | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh
> index 7cb99092938..25c31b0cb1b 100755
> --- a/t/t4023-diff-rename-typechange.sh
> +++ b/t/t4023-diff-rename-typechange.sh
> @@ -52,8 +52,8 @@ test_expect_success setup '
>  '
>  
>  test_expect_success 'cross renames to be detected for regular files' '
> -
> -	git diff-tree five six -r --name-status -B -M | sort >actual &&
> +	git diff-tree five six -r --name-status -B -M >out &&
> +	sort <out >actual &&
>  	{
>  		echo "R100	foo	bar" &&
>  		echo "R100	bar	foo"
> @@ -63,8 +63,8 @@ test_expect_success 'cross renames to be detected for regular files' '
>  '
>  
>  test_expect_success 'cross renames to be detected for typechange' '
> -
> -	git diff-tree one two -r --name-status -B -M | sort >actual &&
> +	git diff-tree one two -r --name-status -B -M >out &&
> +	sort <out >actual &&
>  	{
>  		echo "R100	foo	bar" &&
>  		echo "R100	bar	foo"
> @@ -74,8 +74,8 @@ test_expect_success 'cross renames to be detected for typechange' '
>  '
>  
>  test_expect_success 'moves and renames' '
> -
> -	git diff-tree three four -r --name-status -B -M | sort >actual &&
> +	git diff-tree three four -r --name-status -B -M >out &&
> +	sort <out >actual &&
>  	{
>  		# see -B -M (#6) in t4008
>  		echo "C100	foo	bar" &&

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 8/8] tests: use "test_cmp_cmd" in misc tests
  2022-12-02  0:06   ` [PATCH v2 8/8] tests: use "test_cmp_cmd" in misc tests Ævar Arnfjörð Bjarmason
@ 2022-12-02  2:19     ` Junio C Hamano
  0 siblings, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-02  2:19 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, René Scharfe, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change a few miscellaneous tests to use "test_cmp_cmd" to avoid losing
> the exit code of "git".

The step might have started out to do so, but many of them do not
seem to anymore, perhaps because you allowed the scope of the step
to drift and the focus to be lost while developing more?

>  test_expect_success 'symbolic-ref refuses bare sha1' '
> -	test_must_fail git symbolic-ref HEAD $(git rev-parse HEAD)
> +	rev=$(git rev-parse HEAD) &&
> +	test_must_fail git symbolic-ref HEAD "$rev"

This is not a test_cmp_cmd user.  The update is good.

> diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
> index 5841f280fb2..3e59ffd18a0 100755
> --- a/t/t3701-add-interactive.sh
> +++ b/t/t3701-add-interactive.sh
> @@ -296,9 +296,12 @@ test_expect_success FILEMODE 'stage mode and hunk' '
>  	echo content >>file &&
>  	chmod +x file &&
>  	printf "y\\ny\\n" | git add -p &&
> -	git diff --cached file | grep "new mode" &&
> -	git diff --cached file | grep "+content" &&
> -	test -z "$(git diff file)"
> +	git diff --cached file >out &&
> +	grep "new mode" <out &&
> +	git diff --cached file >out &&
> +	grep "+content" <out &&

No need to run the same "diff --cached file" twice.  No need to
redirect into "grep"; giving the file on the command line is more
natural.

> +	git diff file >out &&
> +	test_must_be_empty out
>  '

Other than that, the above is an improvement, but again, it is not a
test_cmp_cmd user.

> diff --git a/t/t7516-commit-races.sh b/t/t7516-commit-races.sh
> index f2ce14e9071..2d38a16480e 100755
> --- a/t/t7516-commit-races.sh
> +++ b/t/t7516-commit-races.sh
> @@ -10,7 +10,8 @@ test_expect_success 'race to create orphan commit' '
>  	test_must_fail env EDITOR=./hare-editor git commit --allow-empty -m tortoise -e &&
>  	git show -s --pretty=format:%s >subject &&
>  	grep hare subject &&
> -	test -z "$(git show -s --pretty=format:%P)"
> +	git show -s --pretty=format:%P >out &&
> +	test_must_be_empty out
>  '

Likewise.

I guess only half of the tests updated are test_cmp_cmd users, so
this step was about half as big when it was originally written?


^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell
  2022-12-02  1:48       ` Junio C Hamano
@ 2022-12-02  2:45         ` Ævar Arnfjörð Bjarmason
  2022-12-02  9:03           ` Eric Sunshine
  0 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02  2:45 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Eric Sunshine, git, René Scharfe


On Fri, Dec 02 2022, Junio C Hamano wrote:

> Eric Sunshine <sunshine@sunshineco.com> writes:
>
>>>                 git show -s --pretty=oneline "$r" >raw &&
>>> -               cat raw | lf_to_nul || exit 1
>>> +               cat raw | lf_to_nul || return 1
>>>         done >expect &&
>>
>> Using `return 1` here is "obviously correct" since this code is not
>> inside a subshell. Furthermore, the exit code of the for-loop itself
>> is not being lost down a pipe, so `return 1` is indeed an appropriate
>> way to signal failure. Good.
>
> "return 1" is obvious and safe correction.  I have to wonder if
> test_expect_success can be taught to be smarter to intercept "exit"
> so we do not have to bo so careful, but that would be a much more
> involved change to the lower-level of test framework.

I can't think of a way to do so that wouldn't involve running the test
in a sub-shell, which I think would bring us to the state management
problems noted in [1] for Phillip's "test_todo" series, except in this
case we'd have those issues trying to pass state back from the
"test_expect_success".

It's possible, but we'd need to change a lot of code that's expecting to
talk to itself via variables in the same shell to use IPC between
shells, wouldn't we?

1. https://lore.kernel.org/git/221006.86v8owr986.gmgdl@evledraar.gmail.com/

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell
  2022-12-02  1:02     ` Eric Sunshine
  2022-12-02  1:48       ` Junio C Hamano
@ 2022-12-02  3:24       ` Junio C Hamano
  1 sibling, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-02  3:24 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Ævar Arnfjörð Bjarmason, git, René Scharfe

Eric Sunshine <sunshine@sunshineco.com> writes:

>>         for r in $revs
>>         do
>>                 git show -s --pretty=oneline "$r" >raw &&
>> -               cat raw | lf_to_nul || exit 1
>> +               cat raw | lf_to_nul || return 1
>>         done >expect &&
>
> Using `return 1` here is "obviously correct" since this code is not
> inside a subshell.

While it is safe and correct, I wonder if test_expect_success can be
made a bit smarter by somehow capturing what happens inside its
body.  We of course cannot just wrap everything inside a subshell,
as we do want to allow the test body to affect the shell environment
it is running in with its side effects.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 4/8] test-lib-functions: add and use test_cmp_cmd
  2022-12-02  1:45       ` Eric Sunshine
  2022-12-02  1:52         ` Eric Sunshine
@ 2022-12-02  3:41         ` Junio C Hamano
  1 sibling, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-02  3:41 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Ævar Arnfjörð Bjarmason, git, René Scharfe

Eric Sunshine <sunshine@sunshineco.com> writes:

> Another reason I'm "meh" about this function is that it seems too
> narrowly focussed, insisting that the "expect" argument is expressed
> as a one-liner. (Yes, I know that that is not a hard limitation; a
> caller can pass in a multiline string, but still...) Maybe I'd be less
> jaded if it accepted "expect" on its stdin. But, even that doesn't
> seem to buy much. The vast majority of cases where you've converted:
>
>     test "$dir" = "$(test-tool path-utils real_path $dir2)" &&
>
> to:
>
>     test_cmp_cmd "$dir" test-tool path-utils real_path $dir2 &&
>
> could just have easily become:
>
>     echo "$dir" >expect &&
>     test-tool path-utils real_path $dir2 >actual &&
>     test_cmp expect actual
>
> which isn't bad at all, even if it is one line longer, and it is
> idiomatic in this test suite.

[jc: updated the rewritten example]

And it is crystal clear that "expect" and "actual" are clobbered
if written that way.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 2/8] auto-crlf tests: check "git checkout" exit code
  2022-12-02  1:02     ` René Scharfe
  2022-12-02  1:10       ` Eric Sunshine
@ 2022-12-02  5:59       ` Torsten Bögershausen
  2022-12-02  6:03         ` Eric Sunshine
  1 sibling, 1 reply; 83+ messages in thread
From: Torsten Bögershausen @ 2022-12-02  5:59 UTC (permalink / raw)
  To: René Scharfe
  Cc: Ævar Arnfjörð Bjarmason, git, Junio C Hamano,
	Eric Sunshine

On Fri, Dec 02, 2022 at 02:02:55AM +0100, René Scharfe wrote:
> Am 02.12.2022 um 01:06 schrieb Ævar Arnfjörð Bjarmason:
> > Don't hide the exit code from the "git checkout" we run to checkout
> > our attributes file.
> >
> > This fixes cases where we'd have e.g. missed memory leaks under
> > SANITIZE=leak, this code doesn't leak (the relevant "git checkout"
> > leak has been fixed), but in a past version of git we'd continue past
> > this failure under SANITIZE=leak when these invocations had errored
> > out, even under "--immediate".
> >
> > Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> > ---
> >  t/t0027-auto-crlf.sh | 14 ++++++++++----
> >  1 file changed, 10 insertions(+), 4 deletions(-)
> >
> > diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
> > index a94ac1eae37..574344a99db 100755
> > --- a/t/t0027-auto-crlf.sh
> > +++ b/t/t0027-auto-crlf.sh
> > @@ -294,11 +294,17 @@ checkout_files () {
> >  	pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
> >  	for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
> >  	do
> > -		rm crlf_false_attr__$f.txt &&
> > -		if test -z "$ceol"; then
> > -			git checkout -- crlf_false_attr__$f.txt
> > +		if test -z "$ceol"
> > +		then
> > +			test_expect_success "setup $f checkout" '
> > +				rm crlf_false_attr__$f.txt &&
> > +				git checkout -- crlf_false_attr__$f.txt
> > +			'
> >  		else
> > -			git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
> > +			test_expect_success "setup $f checkout with core.eol=$ceol" '
> > +				rm crlf_false_attr__$f.txt &&
> > +				git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
> > +			'
>
> That adds five test_expect_success calls.  Wouldn't one suffice, for the
> whole for loop, and a "|| return 1"?
>
> One line above the context there's a "git config" call that should also
> be covered, right?
>
> Side note: The checkout commands only differ in their -c parameter.
> They could be unified like this, which might simplify handling their
> return code:
>
> 	git ${ceol:+-c core.eol=$ceol} checkout -- crlf_false_attr__$f.txt
>
> >  		fi
> >  	done
> >

That is a nice one. (I learned about the ${:+} yesterday).
Is it supported by all the shells/os combinations ?
If not, we can still extract the if:

        if test -z "$ceol"; then
          CEOL="-c core.eol=$ceol"
        else
          CEOL=""
        fi
        git $CEOL checkout -- crlf_false_attr__$f.txt &&


The original reasoning (for not looking at the return code) was that
if the checkout fails, the test suite will fail further down anyway.
But checking for failures early is a good thing.
Thanks for cleaning up my mess.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 2/8] auto-crlf tests: check "git checkout" exit code
  2022-12-02  5:59       ` Torsten Bögershausen
@ 2022-12-02  6:03         ` Eric Sunshine
  0 siblings, 0 replies; 83+ messages in thread
From: Eric Sunshine @ 2022-12-02  6:03 UTC (permalink / raw)
  To: Torsten Bögershausen
  Cc: René Scharfe, Ævar Arnfjörð Bjarmason, git,
	Junio C Hamano

On Fri, Dec 2, 2022 at 12:59 AM Torsten Bögershausen <tboegi@web.de> wrote:
> On Fri, Dec 02, 2022 at 02:02:55AM +0100, René Scharfe wrote:
> > Side note: The checkout commands only differ in their -c parameter.
> > They could be unified like this, which might simplify handling their
> > return code:
> >
> >       git ${ceol:+-c core.eol=$ceol} checkout -- crlf_false_attr__$f.txt
>
> That is a nice one. (I learned about the ${:+} yesterday).
> Is it supported by all the shells/os combinations ?

${:+} is well supported. It's POSIX. It's used heavily in the Git test
suite already. So, it's safe to use.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell
  2022-12-02  2:45         ` Ævar Arnfjörð Bjarmason
@ 2022-12-02  9:03           ` Eric Sunshine
  2022-12-02 10:02             ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 83+ messages in thread
From: Eric Sunshine @ 2022-12-02  9:03 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: Junio C Hamano, git, René Scharfe

On Fri, Dec 2, 2022 at 3:55 AM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
> On Fri, Dec 02 2022, Junio C Hamano wrote:
> > "return 1" is obvious and safe correction.  I have to wonder if
> > test_expect_success can be taught to be smarter to intercept "exit"
> > so we do not have to bo so careful, but that would be a much more
> > involved change to the lower-level of test framework.
>
> I can't think of a way to do so that wouldn't involve running the test
> in a sub-shell, which I think would bring us to the state management
> problems noted in [1] for Phillip's "test_todo" series, except in this
> case we'd have those issues trying to pass state back from the
> "test_expect_success".
>
> It's possible, but we'd need to change a lot of code that's expecting to
> talk to itself via variables in the same shell to use IPC between
> shells, wouldn't we?

It might make more sense to turn this on its head and make it a
linting issue and simply throw a "?!FOO?!" as is done for other
suspect shell code. In fact, I already have local chainlint.pl patches
which detect whether a subshell is active so that the linter can
complain if it sees `cd` outside of a subshell. I would think that
warning about misuse of `exit 1` outside a subshell (and perhaps
`return 1` inside a subshell) should be possible, though I haven't
thought through all the possibilities.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell
  2022-12-02  9:03           ` Eric Sunshine
@ 2022-12-02 10:02             ` Ævar Arnfjörð Bjarmason
  2022-12-07  6:09               ` Eric Sunshine
  0 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02 10:02 UTC (permalink / raw)
  To: Eric Sunshine; +Cc: Junio C Hamano, git, René Scharfe


On Fri, Dec 02 2022, Eric Sunshine wrote:

> On Fri, Dec 2, 2022 at 3:55 AM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
>> On Fri, Dec 02 2022, Junio C Hamano wrote:
>> > "return 1" is obvious and safe correction.  I have to wonder if
>> > test_expect_success can be taught to be smarter to intercept "exit"
>> > so we do not have to bo so careful, but that would be a much more
>> > involved change to the lower-level of test framework.
>>
>> I can't think of a way to do so that wouldn't involve running the test
>> in a sub-shell, which I think would bring us to the state management
>> problems noted in [1] for Phillip's "test_todo" series, except in this
>> case we'd have those issues trying to pass state back from the
>> "test_expect_success".
>>
>> It's possible, but we'd need to change a lot of code that's expecting to
>> talk to itself via variables in the same shell to use IPC between
>> shells, wouldn't we?
>
> It might make more sense to turn this on its head and make it a
> linting issue and simply throw a "?!FOO?!" as is done for other
> suspect shell code. In fact, I already have local chainlint.pl patches
> which detect whether a subshell is active so that the linter can
> complain if it sees `cd` outside of a subshell. I would think that
> warning about misuse of `exit 1` outside a subshell (and perhaps
> `return 1` inside a subshell) should be possible, though I haven't
> thought through all the possibilities.

That would be great. As a reminder I think (maybe it's not what you have
in mind exactly?) that we had a brief discussion on this topic starting
at [1]. I.e. I was hoping chainlint.pl could be extended to detect
exactly these sort of "test...$(git" patterns (among other things).

This topic doesn't get us there, but once we finally get rid of some of
those patterns it would be nice to have assertions to ensure they don't
come back.

1. https://lore.kernel.org/git/221024.865yg9ecsx.gmgdl@evledraar.gmail.com/

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [PATCH v3 0/8] tests: fix ignored & hidden exit codes
  2022-12-02  0:06 ` [PATCH v2 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                     ` (7 preceding siblings ...)
  2022-12-02  0:06   ` [PATCH v2 8/8] tests: use "test_cmp_cmd" in misc tests Ævar Arnfjörð Bjarmason
@ 2022-12-02 11:52   ` Ævar Arnfjörð Bjarmason
  2022-12-02 11:52     ` [PATCH v3 1/8] merge tests: don't ignore "rev-parse" exit code in helper Ævar Arnfjörð Bjarmason
                       ` (8 more replies)
  8 siblings, 9 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02 11:52 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Various fixes for "git" on the LHS of a pipe, but mostly when in
"test" expressions like:

	test str = "$(git some-command)" &&

Changes since v2
(https://lore.kernel.org/git/cover-v2-0.8-00000000000-20221202T000227Z-avarab@gmail.com/):

 * Ejected 1/8, as René's identical patch has been queued in "seen"
 * The "test_cmp_cmd" helper is gone, instead we just use the same
   three echo/git/test_cmp lines every time.

   I agree that introducing a new helper with some odd semantics was
   probably not a good idea at this time.  It would be nice to do some
   of these as one line, but that probably doesn't justify the helper.

 * Since we're not using the helper the latter part of this series is
   now split up by the category of fix.
 * Rewrote the t0027-auto-crlf.sh commit to address the concerns
   raised.
 * Avid removing redundant code from t7600-merge.sh, and just fix the
   hidden exit code.
 * Small bits here and there, which I think should collectively
   address all outstanding feedback on the v2. Thank all!

Ævar Arnfjörð Bjarmason (8):
  merge tests: don't ignore "rev-parse" exit code in helper
  auto-crlf tests: don't lose exit code in loops and outside tests
  diff tests: fix ignored exit codes in t4023
  t/lib-patch-mode.sh: fix ignored exit codes
  tests: use "test_cmp" instead of "test" in sub-shells
  tests: don't lose 'test <str> = $(cmd ...)"' exit code
  tests: don't lose "git" exit codes in "! ( git ... | grep )"
  tests: don't lose mist "git" exit codes

 t/lib-httpd.sh                     |   5 +-
 t/lib-patch-mode.sh                |  11 ++-
 t/lib-submodule-update.sh          |  26 ++++---
 t/t0001-init.sh                    |   9 ++-
 t/t0002-gitfile.sh                 |   4 +-
 t/t0027-auto-crlf.sh               |  60 +++++++++-------
 t/t0055-beyond-symlinks.sh         |  14 +++-
 t/t0060-path-utils.sh              | 107 +++++++++++++++++++++--------
 t/t0100-previous.sh                |   8 ++-
 t/t1401-symbolic-ref.sh            |   3 +-
 t/t1504-ceiling-dirs.sh            |   8 ++-
 t/t2005-checkout-index-symlinks.sh |   8 ++-
 t/t3200-branch.sh                  |  13 ++--
 t/t3700-add.sh                     |  18 +++--
 t/t3701-add-interactive.sh         |   8 ++-
 t/t4023-diff-rename-typechange.sh  |  12 ++--
 t/t5522-pull-symlink.sh            |   4 +-
 t/t5605-clone-local.sh             |  15 ++--
 t/t7402-submodule-rebase.sh        |  23 +++++--
 t/t7504-commit-msg-hook.sh         |   4 +-
 t/t7516-commit-races.sh            |   3 +-
 t/t7600-merge.sh                   |   2 +-
 t/t7810-grep.sh                    |   4 +-
 23 files changed, 246 insertions(+), 123 deletions(-)

Range-diff against v2:
1:  7c9f8d2830f < -:  ----------- log tests: don't use "exit 1" outside a sub-shell
6:  5715ff7f0f7 ! 1:  64dfec31fb3 merge tests: don't ignore "rev-parse" exit code in helper
    @@ Commit message
         merge tests: don't ignore "rev-parse" exit code in helper
     
         Change the verify_mergeheads() helper the check the exit code of "git
    -    rev-parse". The "$rest" variable added in 274a5c06d52 (merge: record
    -    tag objects without peeling in MERGE_HEAD, 2011-11-07) wasn't being
    -    used.
    -
    -    Such a thing is needed to support the .git/MERGE_HEAD format in
    -    general, but in this case we have no such addition to the line. So
    -    let's compare with "test_cmp" instead, we can always add back this
    -    "$rest" parsing if it's needed in the future.
    +    rev-parse".
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## t/t7600-merge.sh ##
    -@@ t/t7600-merge.sh: verify_parents () {
    - }
    - 
    - verify_mergeheads () {
    --	test_write_lines "$@" >mergehead.expected &&
    --	while read sha1 rest
    -+	for rev in "$@"
    +@@ t/t7600-merge.sh: verify_mergeheads () {
    + 	test_write_lines "$@" >mergehead.expected &&
    + 	while read sha1 rest
      	do
     -		git rev-parse $sha1
    --	done <.git/MERGE_HEAD >mergehead.actual &&
    --	test_cmp mergehead.expected mergehead.actual
    -+		git rev-parse $rev || return 1
    -+	done >mergehead.expected &&
    -+	test_cmp mergehead.expected .git/MERGE_HEAD
    ++		git rev-parse $sha1 || return 1
    + 	done <.git/MERGE_HEAD >mergehead.actual &&
    + 	test_cmp mergehead.expected mergehead.actual
      }
    - 
    - verify_no_mergehead () {
2:  345a667d5bb ! 2:  394d5e46494 auto-crlf tests: check "git checkout" exit code
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    auto-crlf tests: check "git checkout" exit code
    +    auto-crlf tests: don't lose exit code in loops and outside tests
     
    -    Don't hide the exit code from the "git checkout" we run to checkout
    -    our attributes file.
    +    Change the functions which are called from within
    +    "test_expect_success" to add the "|| return 1" idiom to their
    +    for-loops, so we won't lose the exit code of "cp", "git" etc.
     
    -    This fixes cases where we'd have e.g. missed memory leaks under
    +    Then for those setup functions that aren't called from a
    +    "test_expect_success" we need to put the setup code in a
    +    "test_expect_success" as well. It would not be enough to properly
    +    &&-chain these, as the calling code is the top-level script itself. As
    +    we don't run the tests with "set -e" we won't report failing commands
    +    at the top-level.
    +
    +    The "checkout" part of this would miss memory leaks under
         SANITIZE=leak, this code doesn't leak (the relevant "git checkout"
         leak has been fixed), but in a past version of git we'd continue past
         this failure under SANITIZE=leak when these invocations had errored
         out, even under "--immediate".
     
    +    Helped-by: René Scharfe <l.s.r@web.de>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## t/t0027-auto-crlf.sh ##
    +@@ t/t0027-auto-crlf.sh: create_NNO_MIX_files () {
    + 				cp CRLF        ${pfx}_CRLF.txt &&
    + 				cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
    + 				cp LF_mix_CR   ${pfx}_LF_mix_CR.txt &&
    +-				cp CRLF_nul    ${pfx}_CRLF_nul.txt
    ++				cp CRLF_nul    ${pfx}_CRLF_nul.txt ||
    ++				return 1
    + 			done
    + 		done
    + 	done
    +@@ t/t0027-auto-crlf.sh: commit_check_warn () {
    + 	do
    + 		fname=${pfx}_$f.txt &&
    + 		cp $f $fname &&
    +-		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
    ++		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
    ++		return 1
    + 	done &&
    + 	git commit -m "core.autocrlf $crlf" &&
    + 	check_warning "$lfname" ${pfx}_LF.err &&
    +@@ t/t0027-auto-crlf.sh: commit_chk_wrnNNO () {
    + 	lfmixcr=$1 ; shift
    + 	crlfnul=$1 ; shift
    + 	pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
    +-	#Commit files on top of existing file
    +-	create_gitattributes "$attr" $aeol &&
    +-	for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
    +-	do
    +-		fname=${pfx}_$f.txt &&
    +-		cp $f $fname &&
    +-		printf Z >>"$fname" &&
    +-		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
    +-	done
    ++
    ++	test_expect_success 'setup commit NNO files' '
    ++		#Commit files on top of existing file
    ++		create_gitattributes "$attr" $aeol &&
    ++		for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
    ++		do
    ++			fname=${pfx}_$f.txt &&
    ++			cp $f $fname &&
    ++			printf Z >>"$fname" &&
    ++			git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
    ++			return 1
    ++		done
    ++	'
    + 
    + 	test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" '
    + 		check_warning "$lfwarn" ${pfx}_LF.err
    +@@ t/t0027-auto-crlf.sh: commit_MIX_chkwrn () {
    + 	lfmixcr=$1 ; shift
    + 	crlfnul=$1 ; shift
    + 	pfx=MIX_attr_${attr}_aeol_${aeol}_${crlf}
    +-	#Commit file with CLRF_mix_LF on top of existing file
    +-	create_gitattributes "$attr" $aeol &&
    +-	for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
    +-	do
    +-		fname=${pfx}_$f.txt &&
    +-		cp CRLF_mix_LF $fname &&
    +-		printf Z >>"$fname" &&
    +-		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
    +-	done
    ++
    ++	test_expect_success 'setup commit file with mixed EOL' '
    ++		#Commit file with CLRF_mix_LF on top of existing file
    ++		create_gitattributes "$attr" $aeol &&
    ++		for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
    ++		do
    ++			fname=${pfx}_$f.txt &&
    ++			cp CRLF_mix_LF $fname &&
    ++			printf Z >>"$fname" &&
    ++			git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
    ++			return 1
    ++		done
    ++	'
    + 
    + 	test_expect_success "commit file with mixed EOL onto LF crlf=$crlf attr=$attr" '
    + 		check_warning "$lfwarn" ${pfx}_LF.err
     @@ t/t0027-auto-crlf.sh: checkout_files () {
      	pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
      	for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
    @@ t/t0027-auto-crlf.sh: checkout_files () {
     -		rm crlf_false_attr__$f.txt &&
     -		if test -z "$ceol"; then
     -			git checkout -- crlf_false_attr__$f.txt
    -+		if test -z "$ceol"
    -+		then
    -+			test_expect_success "setup $f checkout" '
    -+				rm crlf_false_attr__$f.txt &&
    -+				git checkout -- crlf_false_attr__$f.txt
    -+			'
    - 		else
    +-		else
     -			git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
    -+			test_expect_success "setup $f checkout with core.eol=$ceol" '
    -+				rm crlf_false_attr__$f.txt &&
    -+				git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
    -+			'
    - 		fi
    +-		fi
    ++		test_expect_success "setup $f checkout ${ceol:+ with -c core.eol=$ceol}"  '
    ++			rm -f crlf_false_attr__$f.txt &&
    ++			git ${ceol:+-c core.eol=$ceol} checkout -- crlf_false_attr__$f.txt
    ++		'
      	done
      
    + 	test_expect_success "ls-files --eol attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol" '
3:  c5feef1c808 = 3:  4ec075689f6 diff tests: fix ignored exit codes in t4023
5:  f826a336c3d ! 4:  c080899dd5f t/lib-patch-mode.sh: fix ignored "git" exit codes
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    t/lib-patch-mode.sh: fix ignored "git" exit codes
    +    t/lib-patch-mode.sh: fix ignored exit codes
     
         Fix code added in b319ef70a94 (Add a small patch-mode testing library,
    -    2009-08-13) to use &&-chaining and the newly added "test_cmp_cmd"
    -    instead of interpolating "git" commands in a "test" statement.
    +    2009-08-13) to use &&-chaining and the newly added "test_cmp_cmd".
    +    This avoids losing both the exit code of a "git" and the "cat"
    +    processes.
     
         This fixes cases where we'd have e.g. missed memory leaks under
         SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
    @@ t/lib-patch-mode.sh: set_and_save_state () {
     -	test "$(cat "$1")" = "$2" &&
     -	test "$(git show :"$1")" = "$3"
     +	echo "$2" >expect &&
    -+	cat "$1" >actual &&
    -+	test_cmp expect actual &&
    ++	test_cmp expect "$1" &&
     +
    -+	test_cmp_cmd "$3" git show :"$1"
    ++	echo "$3" >expect &&
    ++	git show :"$1" >actual &&
    ++	test_cmp expect actual
      }
      
      # verify_saved_state <path>
    @@ t/lib-patch-mode.sh: save_head () {
      
      verify_saved_head () {
     -	test "$(cat _head)" = "$(git rev-parse HEAD)"
    -+	test_cmp_cmd "$(cat _head)" git rev-parse HEAD
    ++	git rev-parse HEAD >actual &&
    ++	test_cmp _head actual
      }
7:  d090478aa84 ! 5:  58ac6fe5604 tests: use "test_cmp_cmd" instead of "test" in sub-shells
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    tests: use "test_cmp_cmd" instead of "test" in sub-shells
    +    tests: use "test_cmp" instead of "test" in sub-shells
     
         Convert a few cases where we were using "test" inside a sub-shell, and
         were losing the exit code of "git".
    @@ t/lib-httpd.sh: test_http_push_nonff () {
      		test_must_fail git push -v origin >output 2>&1 &&
     -		(cd "$REMOTE_REPO" &&
     -		 test $HEAD = $(git rev-parse --verify HEAD))
    -+		test_cmp_cmd "$HEAD" git -C "$REMOTE_REPO" rev-parse --verify HEAD
    ++		echo "$HEAD" >expect &&
    ++		git -C "$REMOTE_REPO" rev-parse --verify HEAD >actual &&
    ++		test_cmp expect actual
      	'
      
      	test_expect_success 'non-fast-forward push show ref status' '
    @@ t/lib-submodule-update.sh: replace_gitfile_with_git_dir () {
     -		git config --unset core.worktree
     -	) &&
     +	# does core.worktree point at the right place?
    -+	test_cmp_cmd "../../../$1" git -C ".git/modules/$1" config core.worktree
    ++	echo "../../../$1" >expect &&
    ++	git -C ".git/modules/$1" config core.worktree >actual &&
    ++	test_cmp expect actual &&
     +	# remove it temporarily before comparing, as
     +	# "$1/.git/config" lacks it...
     +	git -C ".git/modules/$1" config --unset core.worktree &&
    @@ t/lib-submodule-update.sh: replace_gitfile_with_git_dir () {
      
      test_git_directory_exists () {
     
    + ## t/t0060-path-utils.sh ##
    +@@ t/t0060-path-utils.sh: test_expect_success 'prefix_path rejects absolute path to dir with same beginnin
    + test_expect_success SYMLINKS 'prefix_path works with absolute path to a symlink to work tree having  same beginning as work tree' '
    + 	git init repo &&
    + 	ln -s repo repolink &&
    +-	test "a" = "$(cd repo && test-tool path-utils prefix_path prefix "$(pwd)/../repolink/a")"
    ++	echo "a" >expect &&
    ++	test-tool -C repo path-utils prefix_path prefix "$(cd repo && pwd)/../repolink/a" >actual &&
    ++	test_cmp expect actual
    + '
    + 
    + relative_path /foo/a/b/c/	/foo/a/b/	c/
    +
      ## t/t3200-branch.sh ##
     @@ t/t3200-branch.sh: test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
      test_expect_success 'git branch -M baz bam should succeed within a worktree in which baz is checked out' '
    @@ t/t3200-branch.sh: test_expect_success 'git branch -M baz bam should succeed whe
     -	) &&
     -	test $(git rev-parse --abbrev-ref HEAD) = bam &&
     +	git -C "$bazdir" branch -M baz bam &&
    -+	test_cmp_cmd "bam" git -C "$bazdir" rev-parse --abbrev-ref HEAD &&
    -+	test_cmp_cmd "bam" git rev-parse --abbrev-ref HEAD &&
    ++	echo "bam" >expect &&
    ++	git -C "$bazdir" rev-parse --abbrev-ref HEAD >actual &&
    ++	test_cmp expect actual &&
    ++	echo "bam" >expect &&
    ++	git rev-parse --abbrev-ref HEAD >actual &&
    ++	test_cmp expect actual &&
      	rm -r bazdir &&
      	git worktree prune
      '
    @@ t/t5605-clone-local.sh: test_expect_success 'preparing origin repository' '
      	git clone --bare . x &&
     -	test "$(cd a.git && git config --bool core.bare)" = true &&
     -	test "$(cd x && git config --bool core.bare)" = true &&
    -+	test_cmp_cmd true git -C a.git config --bool core.bare &&
    -+	test_cmp_cmd true git -C x config --bool core.bare &&
    ++	echo true >expect &&
    ++	git -C a.git config --bool core.bare >actual &&
    ++	test_cmp expect actual &&
    ++	echo true >expect &&
    ++	git -C x config --bool core.bare >actual &&
    ++	test_cmp expect actual &&
      	git bundle create b1.bundle --all &&
      	git bundle create b2.bundle main &&
      	mkdir dir &&
    @@ t/t5605-clone-local.sh: test_expect_success 'preparing origin repository' '
     -	(cd b &&
     -	test "$(git config --bool core.bare)" = false &&
     -	git fetch)
    -+	test_cmp_cmd false git -C b config --bool core.bare &&
    ++	echo false >expect &&
    ++	git -C b config --bool core.bare >actual &&
    ++	test_cmp expect actual &&
     +	git -C b fetch
      '
      
    @@ t/t7402-submodule-rebase.sh: test_expect_success 'stash with a dirty submodule'
      	test new != $(cat file) &&
     -	test submodule = $(git diff --name-only) &&
     -	test $CURRENT = $(cd submodule && git rev-parse HEAD) &&
    -+	test_cmp_cmd submodule git diff --name-only &&
    -+	test_cmp_cmd "$CURRENT" git -C submodule rev-parse HEAD &&
    ++	echo submodule >expect &&
    ++	git diff --name-only >actual &&
    ++	test_cmp expect actual &&
    ++
    ++	echo "$CURRENT" >expect &&
    ++	git -C submodule rev-parse HEAD >actual &&
    ++	test_cmp expect actual &&
    ++
      	git stash apply &&
      	test new = $(cat file) &&
     -	test $CURRENT = $(cd submodule && git rev-parse HEAD)
    -+	test_cmp_cmd "$CURRENT" git -C submodule rev-parse HEAD
    ++	echo "$CURRENT" >expect &&
    ++	git -C submodule rev-parse HEAD >actual &&
    ++	test_cmp expect actual
      
      '
      
4:  c36060934a6 ! 6:  51f32b42ce6 test-lib-functions: add and use test_cmp_cmd
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    test-lib-functions: add and use test_cmp_cmd
    +    tests: don't lose 'test <str> = $(cmd ...)"' exit code
     
    -    Add a "test_cmp_cmd" helper for the common pattern discussed in the
    -    documentation being added here to "t/test-lib-functions.sh".
    +    Convert some cases in the test suite where we'd lose the exit code of
    +    a command being interpolated as one of the arguments to the "test"
    +    builtin function to use &&-chaining and "test_cmp" instead.
     
    -    This implementation leaves the door open for extending this helper
    -    past its obvious limitations, such as:
    +    This way we won't lose the exit code, and the failure output will be
    +    more helpful.
     
    -            test_cmp_cmd "some" "lines" -- <some-cmd>
    -            test_cmp_cmd --stdin <some-cmd> <expect
    -            test_cmp_cmd --ignore-stderr "output" <some-cmd>
    -
    -    By using this in we'll catch cases where "git" or "test-tool"
    -    errors (such as segfaults or abort()) were previously hidden, and we'd
    -    either pass the test, or fail in some subsequent assertion.
    +    In the case of "t0060-path-utils.sh" and
    +    "t2005-checkout-index-symlinks.sh" convert the relevant code to using
    +    the modern style of indentation and newline wrapping while having to
    +    change it.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ t/lib-submodule-update.sh: test_git_directory_exists () {
      	then
      		# does core.worktree point at the right place?
     -		test "$(git -C .git/modules/$1 config core.worktree)" = "../../../$1"
    -+		test_cmp_cmd "../../../$1" git -C ".git/modules/$1" config core.worktree
    ++		echo "../../../$1" >expect &&
    ++		git -C ".git/modules/$1" config core.worktree >actual &&
    ++		test_cmp expect actual
      	fi
      }
      
    @@ t/t0001-init.sh: test_expect_success 'invalid default branch name' '
      	git init rename-initial &&
      	git -C rename-initial branch -m renamed &&
     -	test renamed = $(git -C rename-initial symbolic-ref --short HEAD) &&
    -+	test_cmp_cmd renamed git -C rename-initial symbolic-ref --short HEAD &&
    ++	echo renamed >expect &&
    ++	git -C rename-initial symbolic-ref --short HEAD >actual &&
    ++	test_cmp expect actual &&
    ++
      	git -C rename-initial branch -m renamed again &&
     -	test again = $(git -C rename-initial symbolic-ref --short HEAD)
    -+	test_cmp_cmd again git -C rename-initial symbolic-ref --short HEAD
    ++	echo again >expect &&
    ++	git -C rename-initial symbolic-ref --short HEAD >actual &&
    ++	test_cmp expect actual
      '
      
      test_done
    @@ t/t0002-gitfile.sh: test_expect_success 'bad setup: invalid .git file path' '
      test_expect_success 'final setup + check rev-parse --git-dir' '
      	echo "gitdir: $REAL" >.git &&
     -	test "$REAL" = "$(git rev-parse --git-dir)"
    -+	test_cmp_cmd "$REAL" git rev-parse --git-dir
    ++	echo "$REAL" >expect &&
    ++	git rev-parse --git-dir >actual &&
    ++	test_cmp expect actual
      '
      
      test_expect_success 'check hash-object' '
    @@ t/t0060-path-utils.sh: TEST_PASSES_SANITIZE_LEAK=true
     -	test_expect_success $3 "normalize path: $1 => $2" \
     -	"test \"\$(test-tool path-utils normalize_path_copy '$1')\" = '$expected'"
     +	test_expect_success $3 "normalize path: $1 => $2" "
    -+		test_cmp_cmd '$expected' test-tool path-utils normalize_path_copy '$1'
    ++		echo '$expected' >expect &&
    ++		test-tool path-utils normalize_path_copy '$1' >actual &&
    ++		test_cmp expect actual
     +	"
      }
      
    @@ t/t0060-path-utils.sh: TEST_PASSES_SANITIZE_LEAK=true
     -	test_expect_success $4 "relative path: $1 $2 => $3" \
     -	"test \"\$(test-tool path-utils relative_path '$1' '$2')\" = '$expected'"
     +	test_expect_success $4 "relative path: $1 $2 => $3" "
    -+		test_cmp_cmd '$expected' test-tool path-utils relative_path '$1' '$2'
    ++		echo '$expected' >expect &&
    ++		test-tool path-utils relative_path '$1' '$2' >actual &&
    ++		test_cmp expect actual
     +	"
      }
      
    @@ t/t0060-path-utils.sh: TEST_PASSES_SANITIZE_LEAK=true
      	test_expect_success "test_submodule_relative_url: $1 $2 $3 => $4" "
     -		actual=\$(test-tool submodule resolve-relative-url '$1' '$2' '$3') &&
     -		test \"\$actual\" = '$4'
    -+		test_cmp_cmd '$4' test-tool submodule resolve-relative-url '$1' '$2' '$3'
    ++		echo '$4' >expect &&
    ++		test-tool submodule resolve-relative-url '$1' '$2' '$3' >actual &&
    ++		test_cmp expect actual
      	"
      }
      
    @@ t/t0060-path-utils.sh: ancestor() {
     -	"actual=\$(test-tool path-utils longest_ancestor_length '$1' '$2') &&
     -	 test \"\$actual\" = '$expected'"
     +	test_expect_success $4 "longest ancestor: $1 $2 => $expected" "
    -+		test_cmp_cmd '$expected' test-tool path-utils longest_ancestor_length '$1' '$2'
    ++		echo '$expected' >expect &&
    ++		test-tool path-utils longest_ancestor_length '$1' '$2' >actual &&
    ++		test_cmp expect actual
     +	"
      }
      
    @@ t/t0060-path-utils.sh: ancestor D:/Users/me C:/ -1 MINGW
      
      test_expect_success 'absolute path rejects the empty string' '
     @@ t/t0060-path-utils.sh: test_expect_success 'real path rejects the empty string' '
    + '
      
      test_expect_success POSIX 'real path works on absolute paths 1' '
    ++	echo / >expect &&
    ++	test-tool path-utils real_path "/" >actual &&
    ++	test_cmp expect actual &&
    ++
      	nopath="hopefully-absent-path" &&
     -	test "/" = "$(test-tool path-utils real_path "/")" &&
     -	test "/$nopath" = "$(test-tool path-utils real_path "/$nopath")"
    -+	test_cmp_cmd / test-tool path-utils real_path "/" &&
    -+	test_cmp_cmd "/$nopath" test-tool path-utils real_path "/$nopath"
    ++	echo "/$nopath" >expect &&
    ++	test-tool path-utils real_path "/$nopath" >actual &&
    ++	test_cmp expect actual
      '
      
      test_expect_success 'real path works on absolute paths 2' '
    - 	nopath="hopefully-absent-path" &&
    +-	nopath="hopefully-absent-path" &&
      	# Find an existing top-level directory for the remaining tests:
      	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
     -	test "$d" = "$(test-tool path-utils real_path "$d")" &&
     -	test "$d/$nopath" = "$(test-tool path-utils real_path "$d/$nopath")"
    -+	test_cmp_cmd "$d" test-tool path-utils real_path "$d" &&
    -+	test_cmp_cmd "$d/$nopath" test-tool path-utils real_path "$d/$nopath"
    ++	echo "$d" >expect &&
    ++	test-tool path-utils real_path "$d" >actual &&
    ++	test_cmp expect actual &&
    ++
    ++	nopath="hopefully-absent-path" &&
    ++	echo "$d/$nopath" >expect &&
    ++	test-tool path-utils real_path "$d/$nopath" >actual &&
    ++	test_cmp expect actual
      '
      
      test_expect_success POSIX 'real path removes extra leading slashes' '
    ++	echo "/" >expect &&
    ++	test-tool path-utils real_path "///" >actual &&
    ++	test_cmp expect actual &&
    ++
      	nopath="hopefully-absent-path" &&
     -	test "/" = "$(test-tool path-utils real_path "///")" &&
     -	test "/$nopath" = "$(test-tool path-utils real_path "///$nopath")" &&
    -+	test_cmp_cmd "/" test-tool path-utils real_path "///" &&
    -+	test_cmp_cmd "/$nopath" test-tool path-utils real_path "///$nopath" &&
    ++	echo "/$nopath" >expect &&
    ++	test-tool path-utils real_path "///$nopath" >actual &&
    ++	test_cmp expect actual &&
    ++
      	# Find an existing top-level directory for the remaining tests:
      	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
     -	test "$d" = "$(test-tool path-utils real_path "//$d")" &&
     -	test "$d/$nopath" = "$(test-tool path-utils real_path "//$d/$nopath")"
    -+	test_cmp_cmd "$d" test-tool path-utils real_path "//$d" &&
    -+	test_cmp_cmd "$d/$nopath" test-tool path-utils real_path "//$d/$nopath"
    ++	echo "$d" >expect &&
    ++	test-tool path-utils real_path "//$d" >actual &&
    ++	test_cmp expect actual &&
    ++
    ++	echo "$d/$nopath" >expect &&
    ++	test-tool path-utils real_path "//$d/$nopath" >actual &&
    ++	test_cmp expect actual
      '
      
      test_expect_success 'real path removes other extra slashes' '
    - 	nopath="hopefully-absent-path" &&
    +-	nopath="hopefully-absent-path" &&
      	# Find an existing top-level directory for the remaining tests:
      	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
     -	test "$d" = "$(test-tool path-utils real_path "$d///")" &&
     -	test "$d/$nopath" = "$(test-tool path-utils real_path "$d///$nopath")"
    -+	test_cmp_cmd "$d" test-tool path-utils real_path "$d///" &&
    -+	test_cmp_cmd "$d/$nopath" test-tool path-utils real_path "$d///$nopath"
    ++	echo "$d" >expect &&
    ++	test-tool path-utils real_path "$d///" >actual &&
    ++	test_cmp expect actual &&
    ++
    ++	nopath="hopefully-absent-path" &&
    ++	echo "$d/$nopath" >expect &&
    ++	test-tool path-utils real_path "$d///$nopath" >actual &&
    ++	test_cmp expect actual
      '
      
      test_expect_success SYMLINKS 'real path works on symlinks' '
    @@ t/t0060-path-utils.sh: test_expect_success SYMLINKS 'real path works on symlinks
      	dir="$(cd .git && pwd -P)" &&
      	dir2=third/../second/other/.git &&
     -	test "$dir" = "$(test-tool path-utils real_path $dir2)" &&
    -+	test_cmp_cmd "$dir" test-tool path-utils real_path $dir2 &&
    ++	echo "$dir" >expect &&
    ++	test-tool path-utils real_path $dir2 >actual &&
    ++	test_cmp expect actual &&
      	file="$dir"/index &&
     -	test "$file" = "$(test-tool path-utils real_path $dir2/index)" &&
    -+	test_cmp_cmd "$file" test-tool path-utils real_path $dir2/index &&
    ++	echo "$file" >expect &&
    ++	test-tool path-utils real_path $dir2/index >actual &&
    ++	test_cmp expect actual &&
      	basename=blub &&
     -	test "$dir/$basename" = "$(cd .git && test-tool path-utils real_path "$basename")" &&
    -+	test_cmp_cmd "$dir/$basename" test-tool -C .git path-utils real_path "$basename" &&
    ++	echo "$dir/$basename" >expect &&
    ++	test-tool -C .git path-utils real_path "$basename" >actual &&
    ++	test_cmp expect actual &&
      	ln -s ../first/file .git/syml &&
      	sym="$(cd first && pwd -P)"/file &&
     -	test "$sym" = "$(test-tool path-utils real_path "$dir2/syml")"
    -+	test_cmp_cmd "$sym" test-tool path-utils real_path "$dir2/syml"
    ++	echo "$sym" >expect &&
    ++	test-tool path-utils real_path "$dir2/syml" >actual &&
    ++	test_cmp expect actual
      '
      
      test_expect_success SYMLINKS 'prefix_path works with absolute paths to work tree symlinks' '
      	ln -s target symlink &&
     -	test "$(test-tool path-utils prefix_path prefix "$(pwd)/symlink")" = "symlink"
    -+	test_cmp_cmd "symlink" test-tool path-utils prefix_path prefix "$(pwd)/symlink"
    ++	echo "symlink" >expect &&
    ++	test-tool path-utils prefix_path prefix "$(pwd)/symlink" >actual &&
    ++	test_cmp expect actual
      '
      
      test_expect_success 'prefix_path works with only absolute path to work tree' '
    -@@ t/t0060-path-utils.sh: test_expect_success 'prefix_path rejects absolute path to dir with same beginnin
    - test_expect_success SYMLINKS 'prefix_path works with absolute path to a symlink to work tree having  same beginning as work tree' '
    - 	git init repo &&
    - 	ln -s repo repolink &&
    --	test "a" = "$(cd repo && test-tool path-utils prefix_path prefix "$(pwd)/../repolink/a")"
    -+	test_cmp_cmd "a" test-tool -C repo path-utils prefix_path prefix "$(cd repo && pwd)/../repolink/a"
    - '
    - 
    - relative_path /foo/a/b/c/	/foo/a/b/	c/
     
      ## t/t0100-previous.sh ##
     @@ t/t0100-previous.sh: test_expect_success 'branch -d @{-1}' '
    @@ t/t0100-previous.sh: test_expect_success 'branch -d @{-1}' '
      	git checkout -b junk &&
      	git checkout - &&
     -	test "$(git symbolic-ref HEAD)" = refs/heads/main &&
    -+	test_cmp_cmd refs/heads/main git symbolic-ref HEAD &&
    ++	echo refs/heads/main >expect &&
    ++	git symbolic-ref HEAD >actual &&
    ++	test_cmp expect actual &&
      	git branch -d @{-1} &&
      	test_must_fail git rev-parse --verify refs/heads/junk
      '
    @@ t/t0100-previous.sh: test_expect_success 'branch -d @{-12} when there is not eno
      	git checkout -b junk2 &&
      	git checkout - &&
     -	test "$(git symbolic-ref HEAD)" = refs/heads/main &&
    -+	test_cmp_cmd refs/heads/main git symbolic-ref HEAD &&
    ++	echo refs/heads/main >expect &&
    ++	git symbolic-ref HEAD >actual &&
    ++	test_cmp expect actual &&
      	test_must_fail git branch -d @{-12} &&
      	git rev-parse --verify refs/heads/main
      '
    @@ t/t1504-ceiling-dirs.sh: TEST_PASSES_SANITIZE_LEAK=true
     -	"test '$2' = \"\$(git rev-parse --show-prefix)\""
     +	local expect="$2" &&
     +	test_expect_success "$1: git rev-parse --show-prefix is '$2'" '
    -+		test_cmp_cmd "$expect" git rev-parse --show-prefix
    ++		echo "$expect" >expect &&
    ++		git rev-parse --show-prefix >actual &&
    ++		test_cmp expect actual
     +	'
      }
      
      test_fail() {
     
    - ## t/test-lib-functions.sh ##
    -@@ t/test-lib-functions.sh: test_cmp_rev () {
    - 	fi
    - }
    + ## t/t2005-checkout-index-symlinks.sh ##
    +@@ t/t2005-checkout-index-symlinks.sh: test_expect_success \
    + git checkout-index symlink &&
    + test -f symlink'
      
    -+# test_cmp_cmd is a convenience helper for doing the more verbose:
    -+#
    -+#	echo something >expect &&
    -+#	<some-command-and-args> >actual &&
    -+#	test_cmp expect actual
    -+#
    -+# As:
    -+#
    -+#	test_cmp_cmd something <some-command-and-args>
    -+test_cmp_cmd () {
    -+	local expect="$1" &&
    -+	shift &&
    -+	printf "%s\n" "$expect" >expect &&
    -+	"$@" >actual 2>err &&
    -+	test_must_be_empty err
    +-test_expect_success \
    +-'the file must be the blob we added during the setup' '
    +-test "$(git hash-object -t blob symlink)" = $l'
    ++test_expect_success 'the file must be the blob we added during the setup' '
    ++	echo "$l" >expect &&
    ++	git hash-object -t blob symlink >actual &&
     +	test_cmp expect actual
    -+}
    -+
    - # Compare paths respecting core.ignoreCase
    - test_cmp_fspath () {
    - 	if test "x$1" = "x$2"
    ++'
    + 
    + test_done
    +
    + ## t/t5522-pull-symlink.sh ##
    +@@ t/t5522-pull-symlink.sh: test_expect_success SYMLINKS 'pushing from symlinked subdir' '
    + 		git commit -m push ./file &&
    + 		git push
    + 	) &&
    +-	test push = $(git show HEAD:subdir/file)
    ++	echo push >expect &&
    ++	git show HEAD:subdir/file >actual &&
    ++	test_cmp expect actual
    + '
    + 
    + test_done
    +
    + ## t/t7402-submodule-rebase.sh ##
    +@@ t/t7402-submodule-rebase.sh: chmod a+x fake-editor.sh
    + 
    + test_expect_success 'interactive rebase with a dirty submodule' '
    + 
    +-	test submodule = $(git diff --name-only) &&
    ++	echo submodule >expect &&
    ++	git diff --name-only >actual &&
    ++	test_cmp expect actual &&
    + 	HEAD=$(git rev-parse HEAD) &&
    + 	GIT_EDITOR="\"$(pwd)/fake-editor.sh\"" EDITOR_TEXT="pick $HEAD" \
    + 		git rebase -i HEAD^ &&
    +-	test submodule = $(git diff --name-only)
    +-
    ++	echo submodule >expect &&
    ++	git diff --name-only >actual &&
    ++	test_cmp expect actual
    + '
    + 
    + test_expect_success 'rebase with dirty file and submodule fails' '
    +
    + ## t/t7504-commit-msg-hook.sh ##
    +@@ t/t7504-commit-msg-hook.sh: test_expect_success 'setup: commit-msg hook that always fails' '
    + '
    + 
    + commit_msg_is () {
    +-	test "$(git log --pretty=format:%s%b -1)" = "$1"
    ++	printf "%s" "$1" >expect &&
    ++	git log --pretty=format:%s%b -1 >actual &&
    ++	test_cmp expect actual
    + }
    + 
    + test_expect_success 'with failing hook' '
    +
    + ## t/t7810-grep.sh ##
    +@@ t/t7810-grep.sh: test_expect_success 'log --committer does not search in timestamp' '
    + test_expect_success 'grep with CE_VALID file' '
    + 	git update-index --assume-unchanged t/t &&
    + 	rm t/t &&
    +-	test "$(git grep test)" = "t/t:test" &&
    ++	echo "t/t:test" >expect &&
    ++	git grep test >actual &&
    ++	test_cmp expect actual &&
    + 	git update-index --no-assume-unchanged t/t &&
    + 	git checkout t/t
    + '
-:  ----------- > 7:  307f25db831 tests: don't lose "git" exit codes in "! ( git ... | grep )"
8:  979a7f003f8 ! 8:  37c75f4a097 tests: use "test_cmp_cmd" in misc tests
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    tests: use "test_cmp_cmd" in misc tests
    +    tests: don't lose mist "git" exit codes
     
    -    Change a few miscellaneous tests to use "test_cmp_cmd" to avoid losing
    -    the exit code of "git".
    +    Fix a few miscellaneous cases where:
     
    -    There's many offenders left that match patterns like:
    -
    -            /test .*\$\((test-tool|git)/
    -
    -    What these all have in common is that they were the rare odd cases out
    -    in test files that were otherwise consistently checking the exit code.
    +    - We lost the "git" exit code via "git ... | grep"
    +    - Likewise by having a $(git) argument to git itself
    +    - Used "test -z" to check that a command emitted no output, we can use
    +      "test_must_be_empty" and &&-chaining instead.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ t/t1401-symbolic-ref.sh: test_expect_success 'symbolic-ref refuses non-ref for H
      
      reset_to_sane
     
    - ## t/t2005-checkout-index-symlinks.sh ##
    -@@ t/t2005-checkout-index-symlinks.sh: test -f symlink'
    - 
    - test_expect_success \
    - 'the file must be the blob we added during the setup' '
    --test "$(git hash-object -t blob symlink)" = $l'
    -+test_cmp_cmd "$l" git hash-object -t blob symlink'
    - 
    - test_done
    -
      ## t/t3701-add-interactive.sh ##
     @@ t/t3701-add-interactive.sh: test_expect_success FILEMODE 'stage mode and hunk' '
      	echo content >>file &&
    @@ t/t3701-add-interactive.sh: test_expect_success FILEMODE 'stage mode and hunk' '
     -	git diff --cached file | grep "+content" &&
     -	test -z "$(git diff file)"
     +	git diff --cached file >out &&
    -+	grep "new mode" <out &&
    -+	git diff --cached file >out &&
    -+	grep "+content" <out &&
    ++	grep "new mode" out &&
    ++	grep "+content" out &&
     +	git diff file >out &&
     +	test_must_be_empty out
      '
      
      # end of tests disabled when filemode is not usable
     
    - ## t/t5522-pull-symlink.sh ##
    -@@ t/t5522-pull-symlink.sh: test_expect_success SYMLINKS 'pushing from symlinked subdir' '
    - 		git commit -m push ./file &&
    - 		git push
    - 	) &&
    --	test push = $(git show HEAD:subdir/file)
    -+	test_cmp_cmd push git show HEAD:subdir/file
    - '
    - 
    - test_done
    -
    - ## t/t7402-submodule-rebase.sh ##
    -@@ t/t7402-submodule-rebase.sh: chmod a+x fake-editor.sh
    - 
    - test_expect_success 'interactive rebase with a dirty submodule' '
    - 
    --	test submodule = $(git diff --name-only) &&
    -+	test_cmp_cmd submodule git diff --name-only &&
    - 	HEAD=$(git rev-parse HEAD) &&
    - 	GIT_EDITOR="\"$(pwd)/fake-editor.sh\"" EDITOR_TEXT="pick $HEAD" \
    - 		git rebase -i HEAD^ &&
    --	test submodule = $(git diff --name-only)
    -+	test_cmp_cmd submodule git diff --name-only
    - 
    - '
    - 
    -
    - ## t/t7504-commit-msg-hook.sh ##
    -@@ t/t7504-commit-msg-hook.sh: test_expect_success 'setup: commit-msg hook that always fails' '
    - '
    - 
    - commit_msg_is () {
    --	test "$(git log --pretty=format:%s%b -1)" = "$1"
    -+	test_cmp_cmd "$1" git log --pretty=tformat:%s%b -1
    - }
    - 
    - test_expect_success 'with failing hook' '
    -
      ## t/t7516-commit-races.sh ##
     @@ t/t7516-commit-races.sh: test_expect_success 'race to create orphan commit' '
      	test_must_fail env EDITOR=./hare-editor git commit --allow-empty -m tortoise -e &&
    @@ t/t7516-commit-races.sh: test_expect_success 'race to create orphan commit' '
      '
      
      test_expect_success 'race to create non-orphan commit' '
    -
    - ## t/t7810-grep.sh ##
    -@@ t/t7810-grep.sh: test_expect_success 'log --committer does not search in timestamp' '
    - test_expect_success 'grep with CE_VALID file' '
    - 	git update-index --assume-unchanged t/t &&
    - 	rm t/t &&
    --	test "$(git grep test)" = "t/t:test" &&
    -+	test_cmp_cmd "t/t:test" git grep test &&
    - 	git update-index --no-assume-unchanged t/t &&
    - 	git checkout t/t
    - '
-- 
2.39.0.rc1.981.gf846af54b4b


^ permalink raw reply	[flat|nested] 83+ messages in thread

* [PATCH v3 1/8] merge tests: don't ignore "rev-parse" exit code in helper
  2022-12-02 11:52   ` [PATCH v3 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
@ 2022-12-02 11:52     ` Ævar Arnfjörð Bjarmason
  2022-12-05  0:24       ` Junio C Hamano
  2022-12-02 11:52     ` [PATCH v3 2/8] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
                       ` (7 subsequent siblings)
  8 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02 11:52 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Change the verify_mergeheads() helper the check the exit code of "git
rev-parse".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t7600-merge.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 7c3f6ed9943..060e145957f 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -105,7 +105,7 @@ verify_mergeheads () {
 	test_write_lines "$@" >mergehead.expected &&
 	while read sha1 rest
 	do
-		git rev-parse $sha1
+		git rev-parse $sha1 || return 1
 	done <.git/MERGE_HEAD >mergehead.actual &&
 	test_cmp mergehead.expected mergehead.actual
 }
-- 
2.39.0.rc1.981.gf846af54b4b


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v3 2/8] auto-crlf tests: don't lose exit code in loops and outside tests
  2022-12-02 11:52   ` [PATCH v3 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
  2022-12-02 11:52     ` [PATCH v3 1/8] merge tests: don't ignore "rev-parse" exit code in helper Ævar Arnfjörð Bjarmason
@ 2022-12-02 11:52     ` Ævar Arnfjörð Bjarmason
  2022-12-02 15:59       ` René Scharfe
  2022-12-02 11:52     ` [PATCH v3 3/8] diff tests: fix ignored exit codes in t4023 Ævar Arnfjörð Bjarmason
                       ` (6 subsequent siblings)
  8 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02 11:52 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Change the functions which are called from within
"test_expect_success" to add the "|| return 1" idiom to their
for-loops, so we won't lose the exit code of "cp", "git" etc.

Then for those setup functions that aren't called from a
"test_expect_success" we need to put the setup code in a
"test_expect_success" as well. It would not be enough to properly
&&-chain these, as the calling code is the top-level script itself. As
we don't run the tests with "set -e" we won't report failing commands
at the top-level.

The "checkout" part of this would miss memory leaks under
SANITIZE=leak, this code doesn't leak (the relevant "git checkout"
leak has been fixed), but in a past version of git we'd continue past
this failure under SANITIZE=leak when these invocations had errored
out, even under "--immediate".

Helped-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0027-auto-crlf.sh | 60 +++++++++++++++++++++++++-------------------
 1 file changed, 34 insertions(+), 26 deletions(-)

diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index a94ac1eae37..23f2e613401 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -70,7 +70,8 @@ create_NNO_MIX_files () {
 				cp CRLF        ${pfx}_CRLF.txt &&
 				cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
 				cp LF_mix_CR   ${pfx}_LF_mix_CR.txt &&
-				cp CRLF_nul    ${pfx}_CRLF_nul.txt
+				cp CRLF_nul    ${pfx}_CRLF_nul.txt ||
+				return 1
 			done
 		done
 	done
@@ -101,7 +102,8 @@ commit_check_warn () {
 	do
 		fname=${pfx}_$f.txt &&
 		cp $f $fname &&
-		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
+		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
+		return 1
 	done &&
 	git commit -m "core.autocrlf $crlf" &&
 	check_warning "$lfname" ${pfx}_LF.err &&
@@ -121,15 +123,19 @@ commit_chk_wrnNNO () {
 	lfmixcr=$1 ; shift
 	crlfnul=$1 ; shift
 	pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
-	#Commit files on top of existing file
-	create_gitattributes "$attr" $aeol &&
-	for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
-	do
-		fname=${pfx}_$f.txt &&
-		cp $f $fname &&
-		printf Z >>"$fname" &&
-		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
-	done
+
+	test_expect_success 'setup commit NNO files' '
+		#Commit files on top of existing file
+		create_gitattributes "$attr" $aeol &&
+		for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
+		do
+			fname=${pfx}_$f.txt &&
+			cp $f $fname &&
+			printf Z >>"$fname" &&
+			git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
+			return 1
+		done
+	'
 
 	test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" '
 		check_warning "$lfwarn" ${pfx}_LF.err
@@ -163,15 +169,19 @@ commit_MIX_chkwrn () {
 	lfmixcr=$1 ; shift
 	crlfnul=$1 ; shift
 	pfx=MIX_attr_${attr}_aeol_${aeol}_${crlf}
-	#Commit file with CLRF_mix_LF on top of existing file
-	create_gitattributes "$attr" $aeol &&
-	for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
-	do
-		fname=${pfx}_$f.txt &&
-		cp CRLF_mix_LF $fname &&
-		printf Z >>"$fname" &&
-		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
-	done
+
+	test_expect_success 'setup commit file with mixed EOL' '
+		#Commit file with CLRF_mix_LF on top of existing file
+		create_gitattributes "$attr" $aeol &&
+		for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
+		do
+			fname=${pfx}_$f.txt &&
+			cp CRLF_mix_LF $fname &&
+			printf Z >>"$fname" &&
+			git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
+			return 1
+		done
+	'
 
 	test_expect_success "commit file with mixed EOL onto LF crlf=$crlf attr=$attr" '
 		check_warning "$lfwarn" ${pfx}_LF.err
@@ -294,12 +304,10 @@ checkout_files () {
 	pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
 	for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
 	do
-		rm crlf_false_attr__$f.txt &&
-		if test -z "$ceol"; then
-			git checkout -- crlf_false_attr__$f.txt
-		else
-			git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
-		fi
+		test_expect_success "setup $f checkout ${ceol:+ with -c core.eol=$ceol}"  '
+			rm -f crlf_false_attr__$f.txt &&
+			git ${ceol:+-c core.eol=$ceol} checkout -- crlf_false_attr__$f.txt
+		'
 	done
 
 	test_expect_success "ls-files --eol attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol" '
-- 
2.39.0.rc1.981.gf846af54b4b


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v3 3/8] diff tests: fix ignored exit codes in t4023
  2022-12-02 11:52   ` [PATCH v3 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
  2022-12-02 11:52     ` [PATCH v3 1/8] merge tests: don't ignore "rev-parse" exit code in helper Ævar Arnfjörð Bjarmason
  2022-12-02 11:52     ` [PATCH v3 2/8] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
@ 2022-12-02 11:52     ` Ævar Arnfjörð Bjarmason
  2022-12-05  0:26       ` Junio C Hamano
  2022-12-02 11:52     ` [PATCH v3 4/8] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
                       ` (5 subsequent siblings)
  8 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02 11:52 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Change a "git diff-tree" command to be &&-chained so that we won't
ignore its exit code, see the ea05fd5fbf7 (Merge branch
'ab/keep-git-exit-codes-in-tests', 2022-03-16) topic for prior art.

This fixes code added in b45563a229f (rename: Break filepairs with
different types., 2007-11-30). Due to hiding the exit code we hid a
memory leak under SANITIZE=leak.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t4023-diff-rename-typechange.sh | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh
index 7cb99092938..25c31b0cb1b 100755
--- a/t/t4023-diff-rename-typechange.sh
+++ b/t/t4023-diff-rename-typechange.sh
@@ -52,8 +52,8 @@ test_expect_success setup '
 '
 
 test_expect_success 'cross renames to be detected for regular files' '
-
-	git diff-tree five six -r --name-status -B -M | sort >actual &&
+	git diff-tree five six -r --name-status -B -M >out &&
+	sort <out >actual &&
 	{
 		echo "R100	foo	bar" &&
 		echo "R100	bar	foo"
@@ -63,8 +63,8 @@ test_expect_success 'cross renames to be detected for regular files' '
 '
 
 test_expect_success 'cross renames to be detected for typechange' '
-
-	git diff-tree one two -r --name-status -B -M | sort >actual &&
+	git diff-tree one two -r --name-status -B -M >out &&
+	sort <out >actual &&
 	{
 		echo "R100	foo	bar" &&
 		echo "R100	bar	foo"
@@ -74,8 +74,8 @@ test_expect_success 'cross renames to be detected for typechange' '
 '
 
 test_expect_success 'moves and renames' '
-
-	git diff-tree three four -r --name-status -B -M | sort >actual &&
+	git diff-tree three four -r --name-status -B -M >out &&
+	sort <out >actual &&
 	{
 		# see -B -M (#6) in t4008
 		echo "C100	foo	bar" &&
-- 
2.39.0.rc1.981.gf846af54b4b


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v3 4/8] t/lib-patch-mode.sh: fix ignored exit codes
  2022-12-02 11:52   ` [PATCH v3 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                       ` (2 preceding siblings ...)
  2022-12-02 11:52     ` [PATCH v3 3/8] diff tests: fix ignored exit codes in t4023 Ævar Arnfjörð Bjarmason
@ 2022-12-02 11:52     ` Ævar Arnfjörð Bjarmason
  2022-12-02 15:59       ` René Scharfe
  2022-12-04  0:45       ` Eric Sunshine
  2022-12-02 11:52     ` [PATCH v3 5/8] tests: use "test_cmp" instead of "test" in sub-shells Ævar Arnfjörð Bjarmason
                       ` (4 subsequent siblings)
  8 siblings, 2 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02 11:52 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Fix code added in b319ef70a94 (Add a small patch-mode testing library,
2009-08-13) to use &&-chaining and the newly added "test_cmp_cmd".
This avoids losing both the exit code of a "git" and the "cat"
processes.

This fixes cases where we'd have e.g. missed memory leaks under
SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
discovered it while looking at leaks in related code.

The "cat _head >expect" here is redundant, we could simply give
"_head" to "test_cmp", but let's be consistent in using the "expect"
and "actual" names for clarity.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-patch-mode.sh | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/t/lib-patch-mode.sh b/t/lib-patch-mode.sh
index cfd76bf987b..89ca1f78055 100644
--- a/t/lib-patch-mode.sh
+++ b/t/lib-patch-mode.sh
@@ -29,8 +29,12 @@ set_and_save_state () {
 
 # verify_state <path> <expected-worktree-content> <expected-index-content>
 verify_state () {
-	test "$(cat "$1")" = "$2" &&
-	test "$(git show :"$1")" = "$3"
+	echo "$2" >expect &&
+	test_cmp expect "$1" &&
+
+	echo "$3" >expect &&
+	git show :"$1" >actual &&
+	test_cmp expect actual
 }
 
 # verify_saved_state <path>
@@ -46,5 +50,6 @@ save_head () {
 }
 
 verify_saved_head () {
-	test "$(cat _head)" = "$(git rev-parse HEAD)"
+	git rev-parse HEAD >actual &&
+	test_cmp _head actual
 }
-- 
2.39.0.rc1.981.gf846af54b4b


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v3 5/8] tests: use "test_cmp" instead of "test" in sub-shells
  2022-12-02 11:52   ` [PATCH v3 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                       ` (3 preceding siblings ...)
  2022-12-02 11:52     ` [PATCH v3 4/8] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
@ 2022-12-02 11:52     ` Ævar Arnfjörð Bjarmason
  2022-12-05  0:39       ` Junio C Hamano
  2022-12-02 11:52     ` [PATCH v3 6/8] tests: don't lose 'test <str> = $(cmd ...)"' exit code Ævar Arnfjörð Bjarmason
                       ` (3 subsequent siblings)
  8 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02 11:52 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Convert a few cases where we were using "test" inside a sub-shell, and
were losing the exit code of "git".

In the case of "t3200-branch.sh" some adjacent code outside of a
sub-shell that was losing the exit code is also being converted, as
it's within the same hunk.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-httpd.sh              |  5 +++--
 t/lib-submodule-update.sh   | 22 +++++++++-------------
 t/t0060-path-utils.sh       |  4 +++-
 t/t3200-branch.sh           | 13 +++++++------
 t/t5605-clone-local.sh      | 15 ++++++++++-----
 t/t7402-submodule-rebase.sh | 14 +++++++++++---
 6 files changed, 43 insertions(+), 30 deletions(-)

diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index 608949ea80b..31e7fa3010c 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -217,8 +217,9 @@ test_http_push_nonff () {
 		git commit -a -m path2 --amend &&
 
 		test_must_fail git push -v origin >output 2>&1 &&
-		(cd "$REMOTE_REPO" &&
-		 test $HEAD = $(git rev-parse --verify HEAD))
+		echo "$HEAD" >expect &&
+		git -C "$REMOTE_REPO" rev-parse --verify HEAD >actual &&
+		test_cmp expect actual
 	'
 
 	test_expect_success 'non-fast-forward push show ref status' '
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 2d31fcfda1f..d7c2b670b4a 100644
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -168,20 +168,16 @@ replace_gitfile_with_git_dir () {
 # Note that this only supports submodules at the root level of the
 # superproject, with the default name, i.e. same as its path.
 test_git_directory_is_unchanged () {
-	(
-		cd ".git/modules/$1" &&
-		# does core.worktree point at the right place?
-		test "$(git config core.worktree)" = "../../../$1" &&
-		# remove it temporarily before comparing, as
-		# "$1/.git/config" lacks it...
-		git config --unset core.worktree
-	) &&
+	# does core.worktree point at the right place?
+	echo "../../../$1" >expect &&
+	git -C ".git/modules/$1" config core.worktree >actual &&
+	test_cmp expect actual &&
+	# remove it temporarily before comparing, as
+	# "$1/.git/config" lacks it...
+	git -C ".git/modules/$1" config --unset core.worktree &&
 	diff -r ".git/modules/$1" "$1/.git" &&
-	(
-		# ... and then restore.
-		cd ".git/modules/$1" &&
-		git config core.worktree "../../../$1"
-	)
+	# ... and then restore.
+	git -C ".git/modules/$1" config core.worktree "../../../$1"
 }
 
 test_git_directory_exists () {
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 68e29c904a6..53ec717cbca 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -255,7 +255,9 @@ test_expect_success 'prefix_path rejects absolute path to dir with same beginnin
 test_expect_success SYMLINKS 'prefix_path works with absolute path to a symlink to work tree having  same beginning as work tree' '
 	git init repo &&
 	ln -s repo repolink &&
-	test "a" = "$(cd repo && test-tool path-utils prefix_path prefix "$(pwd)/../repolink/a")"
+	echo "a" >expect &&
+	test-tool -C repo path-utils prefix_path prefix "$(cd repo && pwd)/../repolink/a" >actual &&
+	test_cmp expect actual
 '
 
 relative_path /foo/a/b/c/	/foo/a/b/	c/
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 5a169b68d6a..f5fbb84262b 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -242,12 +242,13 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
 test_expect_success 'git branch -M baz bam should succeed within a worktree in which baz is checked out' '
 	git checkout -b baz &&
 	git worktree add -f bazdir baz &&
-	(
-		cd bazdir &&
-		git branch -M baz bam &&
-		test $(git rev-parse --abbrev-ref HEAD) = bam
-	) &&
-	test $(git rev-parse --abbrev-ref HEAD) = bam &&
+	git -C "$bazdir" branch -M baz bam &&
+	echo "bam" >expect &&
+	git -C "$bazdir" rev-parse --abbrev-ref HEAD >actual &&
+	test_cmp expect actual &&
+	echo "bam" >expect &&
+	git rev-parse --abbrev-ref HEAD >actual &&
+	test_cmp expect actual &&
 	rm -r bazdir &&
 	git worktree prune
 '
diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh
index 38b850c10ef..61a2342bc2c 100755
--- a/t/t5605-clone-local.sh
+++ b/t/t5605-clone-local.sh
@@ -15,8 +15,12 @@ test_expect_success 'preparing origin repository' '
 	: >file && git add . && git commit -m1 &&
 	git clone --bare . a.git &&
 	git clone --bare . x &&
-	test "$(cd a.git && git config --bool core.bare)" = true &&
-	test "$(cd x && git config --bool core.bare)" = true &&
+	echo true >expect &&
+	git -C a.git config --bool core.bare >actual &&
+	test_cmp expect actual &&
+	echo true >expect &&
+	git -C x config --bool core.bare >actual &&
+	test_cmp expect actual &&
 	git bundle create b1.bundle --all &&
 	git bundle create b2.bundle main &&
 	mkdir dir &&
@@ -28,9 +32,10 @@ test_expect_success 'preparing origin repository' '
 
 test_expect_success 'local clone without .git suffix' '
 	git clone -l -s a b &&
-	(cd b &&
-	test "$(git config --bool core.bare)" = false &&
-	git fetch)
+	echo false >expect &&
+	git -C b config --bool core.bare >actual &&
+	test_cmp expect actual &&
+	git -C b fetch
 '
 
 test_expect_success 'local clone with .git suffix' '
diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh
index ebeca12a711..1927a862839 100755
--- a/t/t7402-submodule-rebase.sh
+++ b/t/t7402-submodule-rebase.sh
@@ -82,11 +82,19 @@ test_expect_success 'stash with a dirty submodule' '
 	CURRENT=$(cd submodule && git rev-parse HEAD) &&
 	git stash &&
 	test new != $(cat file) &&
-	test submodule = $(git diff --name-only) &&
-	test $CURRENT = $(cd submodule && git rev-parse HEAD) &&
+	echo submodule >expect &&
+	git diff --name-only >actual &&
+	test_cmp expect actual &&
+
+	echo "$CURRENT" >expect &&
+	git -C submodule rev-parse HEAD >actual &&
+	test_cmp expect actual &&
+
 	git stash apply &&
 	test new = $(cat file) &&
-	test $CURRENT = $(cd submodule && git rev-parse HEAD)
+	echo "$CURRENT" >expect &&
+	git -C submodule rev-parse HEAD >actual &&
+	test_cmp expect actual
 
 '
 
-- 
2.39.0.rc1.981.gf846af54b4b


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v3 6/8] tests: don't lose 'test <str> = $(cmd ...)"' exit code
  2022-12-02 11:52   ` [PATCH v3 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                       ` (4 preceding siblings ...)
  2022-12-02 11:52     ` [PATCH v3 5/8] tests: use "test_cmp" instead of "test" in sub-shells Ævar Arnfjörð Bjarmason
@ 2022-12-02 11:52     ` Ævar Arnfjörð Bjarmason
  2022-12-02 11:52     ` [PATCH v3 7/8] tests: don't lose "git" exit codes in "! ( git ... | grep )" Ævar Arnfjörð Bjarmason
                       ` (2 subsequent siblings)
  8 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02 11:52 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Convert some cases in the test suite where we'd lose the exit code of
a command being interpolated as one of the arguments to the "test"
builtin function to use &&-chaining and "test_cmp" instead.

This way we won't lose the exit code, and the failure output will be
more helpful.

In the case of "t0060-path-utils.sh" and
"t2005-checkout-index-symlinks.sh" convert the relevant code to using
the modern style of indentation and newline wrapping while having to
change it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-submodule-update.sh          |   4 +-
 t/t0001-init.sh                    |   9 ++-
 t/t0002-gitfile.sh                 |   4 +-
 t/t0060-path-utils.sh              | 103 +++++++++++++++++++++--------
 t/t0100-previous.sh                |   8 ++-
 t/t1504-ceiling-dirs.sh            |   8 ++-
 t/t2005-checkout-index-symlinks.sh |   8 ++-
 t/t5522-pull-symlink.sh            |   4 +-
 t/t7402-submodule-rebase.sh        |   9 ++-
 t/t7504-commit-msg-hook.sh         |   4 +-
 t/t7810-grep.sh                    |   4 +-
 11 files changed, 120 insertions(+), 45 deletions(-)

diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index d7c2b670b4a..dee14992c52 100644
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -185,7 +185,9 @@ test_git_directory_exists () {
 	if test -f sub1/.git
 	then
 		# does core.worktree point at the right place?
-		test "$(git -C .git/modules/$1 config core.worktree)" = "../../../$1"
+		echo "../../../$1" >expect &&
+		git -C ".git/modules/$1" config core.worktree >actual &&
+		test_cmp expect actual
 	fi
 }
 
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index d479303efa0..30a6edca1d2 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -598,9 +598,14 @@ test_expect_success 'invalid default branch name' '
 test_expect_success 'branch -m with the initial branch' '
 	git init rename-initial &&
 	git -C rename-initial branch -m renamed &&
-	test renamed = $(git -C rename-initial symbolic-ref --short HEAD) &&
+	echo renamed >expect &&
+	git -C rename-initial symbolic-ref --short HEAD >actual &&
+	test_cmp expect actual &&
+
 	git -C rename-initial branch -m renamed again &&
-	test again = $(git -C rename-initial symbolic-ref --short HEAD)
+	echo again >expect &&
+	git -C rename-initial symbolic-ref --short HEAD >actual &&
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh
index 26eaca095a2..e013d38f485 100755
--- a/t/t0002-gitfile.sh
+++ b/t/t0002-gitfile.sh
@@ -33,7 +33,9 @@ test_expect_success 'bad setup: invalid .git file path' '
 
 test_expect_success 'final setup + check rev-parse --git-dir' '
 	echo "gitdir: $REAL" >.git &&
-	test "$REAL" = "$(git rev-parse --git-dir)"
+	echo "$REAL" >expect &&
+	git rev-parse --git-dir >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'check hash-object' '
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 53ec717cbca..6490ad5ca1b 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -10,20 +10,27 @@ TEST_PASSES_SANITIZE_LEAK=true
 
 norm_path() {
 	expected=$(test-tool path-utils print_path "$2")
-	test_expect_success $3 "normalize path: $1 => $2" \
-	"test \"\$(test-tool path-utils normalize_path_copy '$1')\" = '$expected'"
+	test_expect_success $3 "normalize path: $1 => $2" "
+		echo '$expected' >expect &&
+		test-tool path-utils normalize_path_copy '$1' >actual &&
+		test_cmp expect actual
+	"
 }
 
 relative_path() {
 	expected=$(test-tool path-utils print_path "$3")
-	test_expect_success $4 "relative path: $1 $2 => $3" \
-	"test \"\$(test-tool path-utils relative_path '$1' '$2')\" = '$expected'"
+	test_expect_success $4 "relative path: $1 $2 => $3" "
+		echo '$expected' >expect &&
+		test-tool path-utils relative_path '$1' '$2' >actual &&
+		test_cmp expect actual
+	"
 }
 
 test_submodule_relative_url() {
 	test_expect_success "test_submodule_relative_url: $1 $2 $3 => $4" "
-		actual=\$(test-tool submodule resolve-relative-url '$1' '$2' '$3') &&
-		test \"\$actual\" = '$4'
+		echo '$4' >expect &&
+		test-tool submodule resolve-relative-url '$1' '$2' '$3' >actual &&
+		test_cmp expect actual
 	"
 }
 
@@ -64,9 +71,11 @@ ancestor() {
 		expected=$(($expected-$rootslash+$rootoff))
 		;;
 	esac
-	test_expect_success $4 "longest ancestor: $1 $2 => $expected" \
-	"actual=\$(test-tool path-utils longest_ancestor_length '$1' '$2') &&
-	 test \"\$actual\" = '$expected'"
+	test_expect_success $4 "longest ancestor: $1 $2 => $expected" "
+		echo '$expected' >expect &&
+		test-tool path-utils longest_ancestor_length '$1' '$2' >actual &&
+		test_cmp expect actual
+	"
 }
 
 # Some absolute path tests should be skipped on Windows due to path mangling
@@ -166,8 +175,10 @@ ancestor D:/Users/me C:/ -1 MINGW
 ancestor //server/share/my-directory //server/share/ 14 MINGW
 
 test_expect_success 'strip_path_suffix' '
-	test c:/msysgit = $(test-tool path-utils strip_path_suffix \
-		c:/msysgit/libexec//git-core libexec/git-core)
+	echo c:/msysgit >expect &&
+	test-tool path-utils strip_path_suffix \
+		c:/msysgit/libexec//git-core libexec/git-core >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'absolute path rejects the empty string' '
@@ -188,35 +199,61 @@ test_expect_success 'real path rejects the empty string' '
 '
 
 test_expect_success POSIX 'real path works on absolute paths 1' '
+	echo / >expect &&
+	test-tool path-utils real_path "/" >actual &&
+	test_cmp expect actual &&
+
 	nopath="hopefully-absent-path" &&
-	test "/" = "$(test-tool path-utils real_path "/")" &&
-	test "/$nopath" = "$(test-tool path-utils real_path "/$nopath")"
+	echo "/$nopath" >expect &&
+	test-tool path-utils real_path "/$nopath" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'real path works on absolute paths 2' '
-	nopath="hopefully-absent-path" &&
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "$d")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "$d/$nopath")"
+	echo "$d" >expect &&
+	test-tool path-utils real_path "$d" >actual &&
+	test_cmp expect actual &&
+
+	nopath="hopefully-absent-path" &&
+	echo "$d/$nopath" >expect &&
+	test-tool path-utils real_path "$d/$nopath" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success POSIX 'real path removes extra leading slashes' '
+	echo "/" >expect &&
+	test-tool path-utils real_path "///" >actual &&
+	test_cmp expect actual &&
+
 	nopath="hopefully-absent-path" &&
-	test "/" = "$(test-tool path-utils real_path "///")" &&
-	test "/$nopath" = "$(test-tool path-utils real_path "///$nopath")" &&
+	echo "/$nopath" >expect &&
+	test-tool path-utils real_path "///$nopath" >actual &&
+	test_cmp expect actual &&
+
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "//$d")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "//$d/$nopath")"
+	echo "$d" >expect &&
+	test-tool path-utils real_path "//$d" >actual &&
+	test_cmp expect actual &&
+
+	echo "$d/$nopath" >expect &&
+	test-tool path-utils real_path "//$d/$nopath" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'real path removes other extra slashes' '
-	nopath="hopefully-absent-path" &&
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "$d///")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "$d///$nopath")"
+	echo "$d" >expect &&
+	test-tool path-utils real_path "$d///" >actual &&
+	test_cmp expect actual &&
+
+	nopath="hopefully-absent-path" &&
+	echo "$d/$nopath" >expect &&
+	test-tool path-utils real_path "$d///$nopath" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success SYMLINKS 'real path works on symlinks' '
@@ -227,19 +264,29 @@ test_expect_success SYMLINKS 'real path works on symlinks' '
 	mkdir third &&
 	dir="$(cd .git && pwd -P)" &&
 	dir2=third/../second/other/.git &&
-	test "$dir" = "$(test-tool path-utils real_path $dir2)" &&
+	echo "$dir" >expect &&
+	test-tool path-utils real_path $dir2 >actual &&
+	test_cmp expect actual &&
 	file="$dir"/index &&
-	test "$file" = "$(test-tool path-utils real_path $dir2/index)" &&
+	echo "$file" >expect &&
+	test-tool path-utils real_path $dir2/index >actual &&
+	test_cmp expect actual &&
 	basename=blub &&
-	test "$dir/$basename" = "$(cd .git && test-tool path-utils real_path "$basename")" &&
+	echo "$dir/$basename" >expect &&
+	test-tool -C .git path-utils real_path "$basename" >actual &&
+	test_cmp expect actual &&
 	ln -s ../first/file .git/syml &&
 	sym="$(cd first && pwd -P)"/file &&
-	test "$sym" = "$(test-tool path-utils real_path "$dir2/syml")"
+	echo "$sym" >expect &&
+	test-tool path-utils real_path "$dir2/syml" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success SYMLINKS 'prefix_path works with absolute paths to work tree symlinks' '
 	ln -s target symlink &&
-	test "$(test-tool path-utils prefix_path prefix "$(pwd)/symlink")" = "symlink"
+	echo "symlink" >expect &&
+	test-tool path-utils prefix_path prefix "$(pwd)/symlink" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'prefix_path works with only absolute path to work tree' '
diff --git a/t/t0100-previous.sh b/t/t0100-previous.sh
index a16cc3d2983..70a3223f219 100755
--- a/t/t0100-previous.sh
+++ b/t/t0100-previous.sh
@@ -12,7 +12,9 @@ test_expect_success 'branch -d @{-1}' '
 	test_commit A &&
 	git checkout -b junk &&
 	git checkout - &&
-	test "$(git symbolic-ref HEAD)" = refs/heads/main &&
+	echo refs/heads/main >expect &&
+	git symbolic-ref HEAD >actual &&
+	test_cmp expect actual &&
 	git branch -d @{-1} &&
 	test_must_fail git rev-parse --verify refs/heads/junk
 '
@@ -21,7 +23,9 @@ test_expect_success 'branch -d @{-12} when there is not enough switches yet' '
 	git reflog expire --expire=now &&
 	git checkout -b junk2 &&
 	git checkout - &&
-	test "$(git symbolic-ref HEAD)" = refs/heads/main &&
+	echo refs/heads/main >expect &&
+	git symbolic-ref HEAD >actual &&
+	test_cmp expect actual &&
 	test_must_fail git branch -d @{-12} &&
 	git rev-parse --verify refs/heads/main
 '
diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh
index 0fafcf9dde3..c1679e31d8a 100755
--- a/t/t1504-ceiling-dirs.sh
+++ b/t/t1504-ceiling-dirs.sh
@@ -6,8 +6,12 @@ TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_prefix() {
-	test_expect_success "$1" \
-	"test '$2' = \"\$(git rev-parse --show-prefix)\""
+	local expect="$2" &&
+	test_expect_success "$1: git rev-parse --show-prefix is '$2'" '
+		echo "$expect" >expect &&
+		git rev-parse --show-prefix >actual &&
+		test_cmp expect actual
+	'
 }
 
 test_fail() {
diff --git a/t/t2005-checkout-index-symlinks.sh b/t/t2005-checkout-index-symlinks.sh
index 112682a45a1..67d18cfa104 100755
--- a/t/t2005-checkout-index-symlinks.sh
+++ b/t/t2005-checkout-index-symlinks.sh
@@ -22,8 +22,10 @@ test_expect_success \
 git checkout-index symlink &&
 test -f symlink'
 
-test_expect_success \
-'the file must be the blob we added during the setup' '
-test "$(git hash-object -t blob symlink)" = $l'
+test_expect_success 'the file must be the blob we added during the setup' '
+	echo "$l" >expect &&
+	git hash-object -t blob symlink >actual &&
+	test_cmp expect actual
+'
 
 test_done
diff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh
index bcff460d0a2..9fb73a8c3eb 100755
--- a/t/t5522-pull-symlink.sh
+++ b/t/t5522-pull-symlink.sh
@@ -78,7 +78,9 @@ test_expect_success SYMLINKS 'pushing from symlinked subdir' '
 		git commit -m push ./file &&
 		git push
 	) &&
-	test push = $(git show HEAD:subdir/file)
+	echo push >expect &&
+	git show HEAD:subdir/file >actual &&
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh
index 1927a862839..c74798e8d24 100755
--- a/t/t7402-submodule-rebase.sh
+++ b/t/t7402-submodule-rebase.sh
@@ -55,12 +55,15 @@ chmod a+x fake-editor.sh
 
 test_expect_success 'interactive rebase with a dirty submodule' '
 
-	test submodule = $(git diff --name-only) &&
+	echo submodule >expect &&
+	git diff --name-only >actual &&
+	test_cmp expect actual &&
 	HEAD=$(git rev-parse HEAD) &&
 	GIT_EDITOR="\"$(pwd)/fake-editor.sh\"" EDITOR_TEXT="pick $HEAD" \
 		git rebase -i HEAD^ &&
-	test submodule = $(git diff --name-only)
-
+	echo submodule >expect &&
+	git diff --name-only >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'rebase with dirty file and submodule fails' '
diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh
index a39de8c1126..c0f024eb1ef 100755
--- a/t/t7504-commit-msg-hook.sh
+++ b/t/t7504-commit-msg-hook.sh
@@ -101,7 +101,9 @@ test_expect_success 'setup: commit-msg hook that always fails' '
 '
 
 commit_msg_is () {
-	test "$(git log --pretty=format:%s%b -1)" = "$1"
+	printf "%s" "$1" >expect &&
+	git log --pretty=format:%s%b -1 >actual &&
+	test_cmp expect actual
 }
 
 test_expect_success 'with failing hook' '
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 8eded6ab274..39d6d713ecb 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -1001,7 +1001,9 @@ test_expect_success 'log --committer does not search in timestamp' '
 test_expect_success 'grep with CE_VALID file' '
 	git update-index --assume-unchanged t/t &&
 	rm t/t &&
-	test "$(git grep test)" = "t/t:test" &&
+	echo "t/t:test" >expect &&
+	git grep test >actual &&
+	test_cmp expect actual &&
 	git update-index --no-assume-unchanged t/t &&
 	git checkout t/t
 '
-- 
2.39.0.rc1.981.gf846af54b4b


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v3 7/8] tests: don't lose "git" exit codes in "! ( git ... | grep )"
  2022-12-02 11:52   ` [PATCH v3 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                       ` (5 preceding siblings ...)
  2022-12-02 11:52     ` [PATCH v3 6/8] tests: don't lose 'test <str> = $(cmd ...)"' exit code Ævar Arnfjörð Bjarmason
@ 2022-12-02 11:52     ` Ævar Arnfjörð Bjarmason
  2022-12-02 18:31       ` René Scharfe
  2022-12-02 11:52     ` [PATCH v3 8/8] tests: don't lose mist "git" exit codes Ævar Arnfjörð Bjarmason
  2022-12-19 10:19     ` [PATCH v4 0/6] tests: fix ignored & hidden " Ævar Arnfjörð Bjarmason
  8 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02 11:52 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Change tests that would lose the "git" exit code via a negation
pattern to:

- In the case of "t0055-beyond-symlinks.sh" compare against the
  expected output instead.

- For "t3700-add.sh" use "sed -n" to print the expected "bad" part,
  and use "test_must_be_empty" to assert that it's not there.

  We can also remove a repeated invocation of "git ls-files" for the
  last test that's being modified in that file, and search the
  existing "files" output instead.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0055-beyond-symlinks.sh | 14 ++++++++++++--
 t/t3700-add.sh             | 18 +++++++++++++-----
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/t/t0055-beyond-symlinks.sh b/t/t0055-beyond-symlinks.sh
index 6bada370225..c3eb1158ef9 100755
--- a/t/t0055-beyond-symlinks.sh
+++ b/t/t0055-beyond-symlinks.sh
@@ -15,12 +15,22 @@ test_expect_success SYMLINKS setup '
 
 test_expect_success SYMLINKS 'update-index --add beyond symlinks' '
 	test_must_fail git update-index --add c/d &&
-	! ( git ls-files | grep c/d )
+	cat >expect <<-\EOF &&
+	a
+	b/d
+	EOF
+	git ls-files >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success SYMLINKS 'add beyond symlinks' '
 	test_must_fail git add c/d &&
-	! ( git ls-files | grep c/d )
+	cat >expect <<-\EOF &&
+	a
+	b/d
+	EOF
+	git ls-files >actual &&
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index 51afbd7b24a..82dd768944f 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -106,24 +106,32 @@ test_expect_success '.gitignore test setup' '
 
 test_expect_success '.gitignore is honored' '
 	git add . &&
-	! (git ls-files | grep "\\.ig")
+	git ls-files >files &&
+	sed -n "/\\.ig/p" <files >actual &&
+	test_must_be_empty actual
 '
 
 test_expect_success 'error out when attempting to add ignored ones without -f' '
 	test_must_fail git add a.?? &&
-	! (git ls-files | grep "\\.ig")
+	git ls-files >files &&
+	sed -n "/\\.ig/p" <files >actual &&
+	test_must_be_empty actual
 '
 
 test_expect_success 'error out when attempting to add ignored ones without -f' '
 	test_must_fail git add d.?? &&
-	! (git ls-files | grep "\\.ig")
+	git ls-files >files &&
+	sed -n "/\\.ig/p" <files >actual &&
+	test_must_be_empty actual
 '
 
 test_expect_success 'error out when attempting to add ignored ones but add others' '
 	touch a.if &&
 	test_must_fail git add a.?? &&
-	! (git ls-files | grep "\\.ig") &&
-	(git ls-files | grep a.if)
+	git ls-files >files &&
+	sed -n "/\\.ig/p" <files >actual &&
+	test_must_be_empty actual &&
+	grep a.if files
 '
 
 test_expect_success 'add ignored ones with -f' '
-- 
2.39.0.rc1.981.gf846af54b4b


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v3 8/8] tests: don't lose mist "git" exit codes
  2022-12-02 11:52   ` [PATCH v3 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                       ` (6 preceding siblings ...)
  2022-12-02 11:52     ` [PATCH v3 7/8] tests: don't lose "git" exit codes in "! ( git ... | grep )" Ævar Arnfjörð Bjarmason
@ 2022-12-02 11:52     ` Ævar Arnfjörð Bjarmason
  2022-12-04  0:40       ` Eric Sunshine
  2022-12-19 10:19     ` [PATCH v4 0/6] tests: fix ignored & hidden " Ævar Arnfjörð Bjarmason
  8 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-02 11:52 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Fix a few miscellaneous cases where:

- We lost the "git" exit code via "git ... | grep"
- Likewise by having a $(git) argument to git itself
- Used "test -z" to check that a command emitted no output, we can use
  "test_must_be_empty" and &&-chaining instead.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1401-symbolic-ref.sh    | 3 ++-
 t/t3701-add-interactive.sh | 8 +++++---
 t/t7516-commit-races.sh    | 3 ++-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh
index d708acdb819..5e36899d207 100755
--- a/t/t1401-symbolic-ref.sh
+++ b/t/t1401-symbolic-ref.sh
@@ -33,7 +33,8 @@ test_expect_success 'symbolic-ref refuses non-ref for HEAD' '
 reset_to_sane
 
 test_expect_success 'symbolic-ref refuses bare sha1' '
-	test_must_fail git symbolic-ref HEAD $(git rev-parse HEAD)
+	rev=$(git rev-parse HEAD) &&
+	test_must_fail git symbolic-ref HEAD "$rev"
 '
 
 reset_to_sane
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 5841f280fb2..f1fe5d60677 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -296,9 +296,11 @@ test_expect_success FILEMODE 'stage mode and hunk' '
 	echo content >>file &&
 	chmod +x file &&
 	printf "y\\ny\\n" | git add -p &&
-	git diff --cached file | grep "new mode" &&
-	git diff --cached file | grep "+content" &&
-	test -z "$(git diff file)"
+	git diff --cached file >out &&
+	grep "new mode" out &&
+	grep "+content" out &&
+	git diff file >out &&
+	test_must_be_empty out
 '
 
 # end of tests disabled when filemode is not usable
diff --git a/t/t7516-commit-races.sh b/t/t7516-commit-races.sh
index f2ce14e9071..2d38a16480e 100755
--- a/t/t7516-commit-races.sh
+++ b/t/t7516-commit-races.sh
@@ -10,7 +10,8 @@ test_expect_success 'race to create orphan commit' '
 	test_must_fail env EDITOR=./hare-editor git commit --allow-empty -m tortoise -e &&
 	git show -s --pretty=format:%s >subject &&
 	grep hare subject &&
-	test -z "$(git show -s --pretty=format:%P)"
+	git show -s --pretty=format:%P >out &&
+	test_must_be_empty out
 '
 
 test_expect_success 'race to create non-orphan commit' '
-- 
2.39.0.rc1.981.gf846af54b4b


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* Re: [PATCH v3 2/8] auto-crlf tests: don't lose exit code in loops and outside tests
  2022-12-02 11:52     ` [PATCH v3 2/8] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
@ 2022-12-02 15:59       ` René Scharfe
  0 siblings, 0 replies; 83+ messages in thread
From: René Scharfe @ 2022-12-02 15:59 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git
  Cc: Junio C Hamano, Eric Sunshine, Torsten Bögershausen

Am 02.12.22 um 12:52 schrieb Ævar Arnfjörð Bjarmason:
> Change the functions which are called from within
> "test_expect_success" to add the "|| return 1" idiom to their
> for-loops, so we won't lose the exit code of "cp", "git" etc.
>
> Then for those setup functions that aren't called from a
> "test_expect_success" we need to put the setup code in a
> "test_expect_success" as well. It would not be enough to properly
> &&-chain these, as the calling code is the top-level script itself. As
> we don't run the tests with "set -e" we won't report failing commands
> at the top-level.
>
> The "checkout" part of this would miss memory leaks under
> SANITIZE=leak, this code doesn't leak (the relevant "git checkout"
> leak has been fixed), but in a past version of git we'd continue past
> this failure under SANITIZE=leak when these invocations had errored
> out, even under "--immediate".
>
> Helped-by: René Scharfe <l.s.r@web.de>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t0027-auto-crlf.sh | 60 +++++++++++++++++++++++++-------------------
>  1 file changed, 34 insertions(+), 26 deletions(-)
>
> diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
> index a94ac1eae37..23f2e613401 100755
> --- a/t/t0027-auto-crlf.sh
> +++ b/t/t0027-auto-crlf.sh
> @@ -70,7 +70,8 @@ create_NNO_MIX_files () {
>  				cp CRLF        ${pfx}_CRLF.txt &&
>  				cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
>  				cp LF_mix_CR   ${pfx}_LF_mix_CR.txt &&
> -				cp CRLF_nul    ${pfx}_CRLF_nul.txt
> +				cp CRLF_nul    ${pfx}_CRLF_nul.txt ||
> +				return 1
>  			done
>  		done
>  	done
> @@ -101,7 +102,8 @@ commit_check_warn () {
>  	do
>  		fname=${pfx}_$f.txt &&
>  		cp $f $fname &&
> -		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
> +		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
> +		return 1
>  	done &&
>  	git commit -m "core.autocrlf $crlf" &&
>  	check_warning "$lfname" ${pfx}_LF.err &&
> @@ -121,15 +123,19 @@ commit_chk_wrnNNO () {
>  	lfmixcr=$1 ; shift
>  	crlfnul=$1 ; shift
>  	pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
> -	#Commit files on top of existing file
> -	create_gitattributes "$attr" $aeol &&
> -	for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
> -	do
> -		fname=${pfx}_$f.txt &&
> -		cp $f $fname &&
> -		printf Z >>"$fname" &&
> -		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
> -	done
> +
> +	test_expect_success 'setup commit NNO files' '
> +		#Commit files on top of existing file
> +		create_gitattributes "$attr" $aeol &&
> +		for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
> +		do
> +			fname=${pfx}_$f.txt &&
> +			cp $f $fname &&
> +			printf Z >>"$fname" &&
> +			git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
> +			return 1
> +		done
> +	'
>
>  	test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" '
>  		check_warning "$lfwarn" ${pfx}_LF.err
> @@ -163,15 +169,19 @@ commit_MIX_chkwrn () {
>  	lfmixcr=$1 ; shift
>  	crlfnul=$1 ; shift
>  	pfx=MIX_attr_${attr}_aeol_${aeol}_${crlf}
> -	#Commit file with CLRF_mix_LF on top of existing file
> -	create_gitattributes "$attr" $aeol &&
> -	for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
> -	do
> -		fname=${pfx}_$f.txt &&
> -		cp CRLF_mix_LF $fname &&
> -		printf Z >>"$fname" &&
> -		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
> -	done
> +
> +	test_expect_success 'setup commit file with mixed EOL' '
> +		#Commit file with CLRF_mix_LF on top of existing file
> +		create_gitattributes "$attr" $aeol &&
> +		for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
> +		do
> +			fname=${pfx}_$f.txt &&
> +			cp CRLF_mix_LF $fname &&
> +			printf Z >>"$fname" &&
> +			git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
> +			return 1
> +		done
> +	'
>
>  	test_expect_success "commit file with mixed EOL onto LF crlf=$crlf attr=$attr" '
>  		check_warning "$lfwarn" ${pfx}_LF.err
> @@ -294,12 +304,10 @@ checkout_files () {

The context lines right here are:

	create_gitattributes "$attr" $ident $aeol &&
	git config core.autocrlf $crlf &&

Those better be covered by test_expect_success as well, right?  Wrap them and
the whole loop in a single test_expect_success, like you did above?

>  	pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
>  	for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
>  	do
> -		rm crlf_false_attr__$f.txt &&
> -		if test -z "$ceol"; then
> -			git checkout -- crlf_false_attr__$f.txt
> -		else
> -			git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
> -		fi
> +		test_expect_success "setup $f checkout ${ceol:+ with -c core.eol=$ceol}"  '
> +			rm -f crlf_false_attr__$f.txt &&
> +			git ${ceol:+-c core.eol=$ceol} checkout -- crlf_false_attr__$f.txt
> +		'
>  	done
>
>  	test_expect_success "ls-files --eol attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol" '

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v3 4/8] t/lib-patch-mode.sh: fix ignored exit codes
  2022-12-02 11:52     ` [PATCH v3 4/8] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
@ 2022-12-02 15:59       ` René Scharfe
  2022-12-04  0:45       ` Eric Sunshine
  1 sibling, 0 replies; 83+ messages in thread
From: René Scharfe @ 2022-12-02 15:59 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git
  Cc: Junio C Hamano, Eric Sunshine, Torsten Bögershausen

Am 02.12.22 um 12:52 schrieb Ævar Arnfjörð Bjarmason:
> Fix code added in b319ef70a94 (Add a small patch-mode testing library,
> 2009-08-13) to use &&-chaining and the newly added "test_cmp_cmd".
> This avoids losing both the exit code of a "git" and the "cat"
> processes.
>
> This fixes cases where we'd have e.g. missed memory leaks under
> SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
> discovered it while looking at leaks in related code.
>
> The "cat _head >expect" here is redundant, we could simply give
> "_head" to "test_cmp", but let's be consistent in using the "expect"
> and "actual" names for clarity.

The code at the bottom uses _head directly, which is fine IMHO, but then
this sentence should go.

>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/lib-patch-mode.sh | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/t/lib-patch-mode.sh b/t/lib-patch-mode.sh
> index cfd76bf987b..89ca1f78055 100644
> --- a/t/lib-patch-mode.sh
> +++ b/t/lib-patch-mode.sh
> @@ -29,8 +29,12 @@ set_and_save_state () {
>
>  # verify_state <path> <expected-worktree-content> <expected-index-content>
>  verify_state () {
> -	test "$(cat "$1")" = "$2" &&
> -	test "$(git show :"$1")" = "$3"
> +	echo "$2" >expect &&
> +	test_cmp expect "$1" &&
> +
> +	echo "$3" >expect &&
> +	git show :"$1" >actual &&
> +	test_cmp expect actual
>  }
>
>  # verify_saved_state <path>
> @@ -46,5 +50,6 @@ save_head () {
>  }
>
>  verify_saved_head () {
> -	test "$(cat _head)" = "$(git rev-parse HEAD)"
> +	git rev-parse HEAD >actual &&
> +	test_cmp _head actual
>  }

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v3 7/8] tests: don't lose "git" exit codes in "! ( git ... | grep )"
  2022-12-02 11:52     ` [PATCH v3 7/8] tests: don't lose "git" exit codes in "! ( git ... | grep )" Ævar Arnfjörð Bjarmason
@ 2022-12-02 18:31       ` René Scharfe
  0 siblings, 0 replies; 83+ messages in thread
From: René Scharfe @ 2022-12-02 18:31 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git
  Cc: Junio C Hamano, Eric Sunshine, Torsten Bögershausen

Am 02.12.22 um 12:52 schrieb Ævar Arnfjörð Bjarmason:
> Change tests that would lose the "git" exit code via a negation
> pattern to:
>
> - In the case of "t0055-beyond-symlinks.sh" compare against the
>   expected output instead.
>
> - For "t3700-add.sh" use "sed -n" to print the expected "bad" part,
>   and use "test_must_be_empty" to assert that it's not there.
>
>   We can also remove a repeated invocation of "git ls-files" for the
>   last test that's being modified in that file, and search the
>   existing "files" output instead.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t0055-beyond-symlinks.sh | 14 ++++++++++++--
>  t/t3700-add.sh             | 18 +++++++++++++-----
>  2 files changed, 25 insertions(+), 7 deletions(-)
>
> diff --git a/t/t0055-beyond-symlinks.sh b/t/t0055-beyond-symlinks.sh
> index 6bada370225..c3eb1158ef9 100755
> --- a/t/t0055-beyond-symlinks.sh
> +++ b/t/t0055-beyond-symlinks.sh
> @@ -15,12 +15,22 @@ test_expect_success SYMLINKS setup '
>
>  test_expect_success SYMLINKS 'update-index --add beyond symlinks' '
>  	test_must_fail git update-index --add c/d &&
> -	! ( git ls-files | grep c/d )
> +	cat >expect <<-\EOF &&
> +	a
> +	b/d
> +	EOF
> +	git ls-files >actual &&
> +	test_cmp expect actual
>  '

Hmm, this makes the test depend on the other files.  Adding more of them
for a different test now requires updating this test as well.  Why not
handle it like you did in t3700 below?

>
>  test_expect_success SYMLINKS 'add beyond symlinks' '
>  	test_must_fail git add c/d &&
> -	! ( git ls-files | grep c/d )
> +	cat >expect <<-\EOF &&
> +	a
> +	b/d
> +	EOF
> +	git ls-files >actual &&
> +	test_cmp expect actual
>  '

Same here.

>
>  test_done
> diff --git a/t/t3700-add.sh b/t/t3700-add.sh
> index 51afbd7b24a..82dd768944f 100755
> --- a/t/t3700-add.sh
> +++ b/t/t3700-add.sh
> @@ -106,24 +106,32 @@ test_expect_success '.gitignore test setup' '
>
>  test_expect_success '.gitignore is honored' '
>  	git add . &&
> -	! (git ls-files | grep "\\.ig")
> +	git ls-files >files &&
> +	sed -n "/\\.ig/p" <files >actual &&
> +	test_must_be_empty actual
>  '

You use sed instead of grep because no match is expected and sed returns
0 even then, while grep would exit with code 1, correct?  OK.

Can we use that, though?  I.e. how about this?

	git ls-files >files &&
	test_expect_code 1 grep "\\.ig" files

It would print the unexpected lines in verbose mode like this:

	expecting success of 3700.12 '.gitignore is honored':
		git add . &&
		git ls-files >files &&
		echo foo.ig >files &&	# inject bogus value
		test_expect_code 1 grep "\\.ig" files

	foo.ig
	test_expect_code: command exited with 0, we wanted 1 grep \.ig files

Or can we trust ls-files' own filtering?

	git ls-files "*.ig" >actual &&
	test_must_be_empty actual

Both variants are shorter and should be slightly faster, which can
matter if we use that pattern more widely.

(Didn't measure here, but from a recent foray into t3920 on Windows I
took home that removing commands has a small, but measurable impact there:
https://lore.kernel.org/git/203cb627-2423-8a35-d280-9f9ffc66e072@web.de/T/#u)

>
>  test_expect_success 'error out when attempting to add ignored ones without -f' '
>  	test_must_fail git add a.?? &&
> -	! (git ls-files | grep "\\.ig")
> +	git ls-files >files &&
> +	sed -n "/\\.ig/p" <files >actual &&
> +	test_must_be_empty actual
>  '
>
>  test_expect_success 'error out when attempting to add ignored ones without -f' '
>  	test_must_fail git add d.?? &&
> -	! (git ls-files | grep "\\.ig")
> +	git ls-files >files &&
> +	sed -n "/\\.ig/p" <files >actual &&
> +	test_must_be_empty actual
>  '
>
>  test_expect_success 'error out when attempting to add ignored ones but add others' '
>  	touch a.if &&
>  	test_must_fail git add a.?? &&
> -	! (git ls-files | grep "\\.ig") &&
> -	(git ls-files | grep a.if)
> +	git ls-files >files &&
> +	sed -n "/\\.ig/p" <files >actual &&
> +	test_must_be_empty actual &&
> +	grep a.if files
>  '
>
>  test_expect_success 'add ignored ones with -f' '

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v3 8/8] tests: don't lose mist "git" exit codes
  2022-12-02 11:52     ` [PATCH v3 8/8] tests: don't lose mist "git" exit codes Ævar Arnfjörð Bjarmason
@ 2022-12-04  0:40       ` Eric Sunshine
  2022-12-05  0:45         ` Junio C Hamano
  0 siblings, 1 reply; 83+ messages in thread
From: Eric Sunshine @ 2022-12-04  0:40 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, René Scharfe, Torsten Bögershausen

On Fri, Dec 2, 2022 at 6:53 AM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
> tests: don't lose mist "git" exit codes

"mist"?

> Fix a few miscellaneous cases where:
>
> - We lost the "git" exit code via "git ... | grep"
> - Likewise by having a $(git) argument to git itself
> - Used "test -z" to check that a command emitted no output, we can use
>   "test_must_be_empty" and &&-chaining instead.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v3 4/8] t/lib-patch-mode.sh: fix ignored exit codes
  2022-12-02 11:52     ` [PATCH v3 4/8] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
  2022-12-02 15:59       ` René Scharfe
@ 2022-12-04  0:45       ` Eric Sunshine
  1 sibling, 0 replies; 83+ messages in thread
From: Eric Sunshine @ 2022-12-04  0:45 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, René Scharfe, Torsten Bögershausen

On Fri, Dec 2, 2022 at 6:53 AM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
> Fix code added in b319ef70a94 (Add a small patch-mode testing library,
> 2009-08-13) to use &&-chaining and the newly added "test_cmp_cmd".
> This avoids losing both the exit code of a "git" and the "cat"
> processes.

This still talks about test_cmp_cmd() which is no longer present in v3.

> This fixes cases where we'd have e.g. missed memory leaks under
> SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
> discovered it while looking at leaks in related code.
>
> The "cat _head >expect" here is redundant, we could simply give
> "_head" to "test_cmp", but let's be consistent in using the "expect"
> and "actual" names for clarity.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v3 1/8] merge tests: don't ignore "rev-parse" exit code in helper
  2022-12-02 11:52     ` [PATCH v3 1/8] merge tests: don't ignore "rev-parse" exit code in helper Ævar Arnfjörð Bjarmason
@ 2022-12-05  0:24       ` Junio C Hamano
  0 siblings, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-05  0:24 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, René Scharfe, Eric Sunshine, Torsten Bögershausen

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Subject: Re: [PATCH v3 1/8] merge tests: don't ignore "rev-parse" exit code in helper

Just one is inclded here, so I'll retitle (and I am tempted to
disassemble the "series" into separate individual topics, as that
will help to use good bits early without getting distracted by the
rest) this to something like "s/^[^:]*:/t7600:/"

> Change the verify_mergeheads() helper the check the exit code of "git
> rev-parse".
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t7600-merge.sh | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Thanks.

>
> diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
> index 7c3f6ed9943..060e145957f 100755
> --- a/t/t7600-merge.sh
> +++ b/t/t7600-merge.sh
> @@ -105,7 +105,7 @@ verify_mergeheads () {
>  	test_write_lines "$@" >mergehead.expected &&
>  	while read sha1 rest
>  	do
> -		git rev-parse $sha1
> +		git rev-parse $sha1 || return 1
>  	done <.git/MERGE_HEAD >mergehead.actual &&
>  	test_cmp mergehead.expected mergehead.actual
>  }

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v3 3/8] diff tests: fix ignored exit codes in t4023
  2022-12-02 11:52     ` [PATCH v3 3/8] diff tests: fix ignored exit codes in t4023 Ævar Arnfjörð Bjarmason
@ 2022-12-05  0:26       ` Junio C Hamano
  0 siblings, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-05  0:26 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, René Scharfe, Eric Sunshine, Torsten Bögershausen

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change a "git diff-tree" command to be &&-chained so that we won't
> ignore its exit code, see the ea05fd5fbf7 (Merge branch
> 'ab/keep-git-exit-codes-in-tests', 2022-03-16) topic for prior art.
>
> This fixes code added in b45563a229f (rename: Break filepairs with
> different types., 2007-11-30). Due to hiding the exit code we hid a
> memory leak under SANITIZE=leak.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t4023-diff-rename-typechange.sh | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)

I already have this as 1ebeb849 (diff tests: fix ignored exit codes
in t4023, 2022-12-02) on ab/t4023-avoid-losing-exit-status-of-diff
topic.

Thanks.


>
> diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh
> index 7cb99092938..25c31b0cb1b 100755
> --- a/t/t4023-diff-rename-typechange.sh
> +++ b/t/t4023-diff-rename-typechange.sh
> @@ -52,8 +52,8 @@ test_expect_success setup '
>  '
>  
>  test_expect_success 'cross renames to be detected for regular files' '
> -
> -	git diff-tree five six -r --name-status -B -M | sort >actual &&
> +	git diff-tree five six -r --name-status -B -M >out &&
> +	sort <out >actual &&
>  	{
>  		echo "R100	foo	bar" &&
>  		echo "R100	bar	foo"
> @@ -63,8 +63,8 @@ test_expect_success 'cross renames to be detected for regular files' '
>  '
>  
>  test_expect_success 'cross renames to be detected for typechange' '
> -
> -	git diff-tree one two -r --name-status -B -M | sort >actual &&
> +	git diff-tree one two -r --name-status -B -M >out &&
> +	sort <out >actual &&
>  	{
>  		echo "R100	foo	bar" &&
>  		echo "R100	bar	foo"
> @@ -74,8 +74,8 @@ test_expect_success 'cross renames to be detected for typechange' '
>  '
>  
>  test_expect_success 'moves and renames' '
> -
> -	git diff-tree three four -r --name-status -B -M | sort >actual &&
> +	git diff-tree three four -r --name-status -B -M >out &&
> +	sort <out >actual &&
>  	{
>  		# see -B -M (#6) in t4008
>  		echo "C100	foo	bar" &&

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v3 5/8] tests: use "test_cmp" instead of "test" in sub-shells
  2022-12-02 11:52     ` [PATCH v3 5/8] tests: use "test_cmp" instead of "test" in sub-shells Ævar Arnfjörð Bjarmason
@ 2022-12-05  0:39       ` Junio C Hamano
  0 siblings, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-05  0:39 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, René Scharfe, Eric Sunshine, Torsten Bögershausen

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Convert a few cases where we were using "test" inside a sub-shell, and
> were losing the exit code of "git".

That makes it sound like

	(
		cd there &&
		a=$(git something expected to be silent) &&
		test -z "$a"
	) &&
	...

is bad, and it can be improved somehow by using "test_cmp" instead
of "test", but I do not think that is what you meant (in fact, the
command substitution used above is safe and we catch failing git).

After looking at a few samples from the patch s/sub-shell/command
substitution/ might be what you meant, i.e.

	test -z "$(git something) &&
	...

is bad and we want 

	git something >out &&
	! test -s out

to keep the exit code from "git".  IOW, fixing the lossage of exit
code has little to do with the use of test vs test_cmp.

Perhaps retitle to

    Subject: [PATCH] tests: avoid "test op $(git foo)" lose exit status of git

    Rewrite tests that ran "git" inside command substitution and
    lost exit status of "git" so that we notice failing "git".

or something like that.

> In the case of "t3200-branch.sh" some adjacent code outside of a
> sub-shell that was losing the exit code is also being converted, as
> it's within the same hunk.

Again s/sub-shell/command substitution?, I think.

> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/lib-httpd.sh              |  5 +++--
>  t/lib-submodule-update.sh   | 22 +++++++++-------------
>  t/t0060-path-utils.sh       |  4 +++-
>  t/t3200-branch.sh           | 13 +++++++------
>  t/t5605-clone-local.sh      | 15 ++++++++++-----
>  t/t7402-submodule-rebase.sh | 14 +++++++++++---
>  6 files changed, 43 insertions(+), 30 deletions(-)
>
> diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
> index 608949ea80b..31e7fa3010c 100644
> --- a/t/lib-httpd.sh
> +++ b/t/lib-httpd.sh
> @@ -217,8 +217,9 @@ test_http_push_nonff () {
>  		git commit -a -m path2 --amend &&
>  
>  		test_must_fail git push -v origin >output 2>&1 &&
> -		(cd "$REMOTE_REPO" &&
> -		 test $HEAD = $(git rev-parse --verify HEAD))
> +		echo "$HEAD" >expect &&
> +		git -C "$REMOTE_REPO" rev-parse --verify HEAD >actual &&
> +		test_cmp expect actual
>  	'
>  
>  	test_expect_success 'non-fast-forward push show ref status' '
> diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
> index 2d31fcfda1f..d7c2b670b4a 100644
> --- a/t/lib-submodule-update.sh
> +++ b/t/lib-submodule-update.sh
> @@ -168,20 +168,16 @@ replace_gitfile_with_git_dir () {
>  # Note that this only supports submodules at the root level of the
>  # superproject, with the default name, i.e. same as its path.
>  test_git_directory_is_unchanged () {
> -	(
> -		cd ".git/modules/$1" &&
> -		# does core.worktree point at the right place?
> -		test "$(git config core.worktree)" = "../../../$1" &&
> -		# remove it temporarily before comparing, as
> -		# "$1/.git/config" lacks it...
> -		git config --unset core.worktree
> -	) &&
> +	# does core.worktree point at the right place?
> +	echo "../../../$1" >expect &&
> +	git -C ".git/modules/$1" config core.worktree >actual &&
> +	test_cmp expect actual &&
> +	# remove it temporarily before comparing, as
> +	# "$1/.git/config" lacks it...
> +	git -C ".git/modules/$1" config --unset core.worktree &&
>  	diff -r ".git/modules/$1" "$1/.git" &&
> -	(
> -		# ... and then restore.
> -		cd ".git/modules/$1" &&
> -		git config core.worktree "../../../$1"
> -	)
> +	# ... and then restore.
> +	git -C ".git/modules/$1" config core.worktree "../../../$1"
>  }
>  
>  test_git_directory_exists () {
> diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
> index 68e29c904a6..53ec717cbca 100755
> --- a/t/t0060-path-utils.sh
> +++ b/t/t0060-path-utils.sh
> @@ -255,7 +255,9 @@ test_expect_success 'prefix_path rejects absolute path to dir with same beginnin
>  test_expect_success SYMLINKS 'prefix_path works with absolute path to a symlink to work tree having  same beginning as work tree' '
>  	git init repo &&
>  	ln -s repo repolink &&
> -	test "a" = "$(cd repo && test-tool path-utils prefix_path prefix "$(pwd)/../repolink/a")"
> +	echo "a" >expect &&
> +	test-tool -C repo path-utils prefix_path prefix "$(cd repo && pwd)/../repolink/a" >actual &&
> +	test_cmp expect actual
>  '
>  
>  relative_path /foo/a/b/c/	/foo/a/b/	c/
> diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
> index 5a169b68d6a..f5fbb84262b 100755
> --- a/t/t3200-branch.sh
> +++ b/t/t3200-branch.sh
> @@ -242,12 +242,13 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
>  test_expect_success 'git branch -M baz bam should succeed within a worktree in which baz is checked out' '
>  	git checkout -b baz &&
>  	git worktree add -f bazdir baz &&
> -	(
> -		cd bazdir &&
> -		git branch -M baz bam &&
> -		test $(git rev-parse --abbrev-ref HEAD) = bam
> -	) &&
> -	test $(git rev-parse --abbrev-ref HEAD) = bam &&
> +	git -C "$bazdir" branch -M baz bam &&
> +	echo "bam" >expect &&
> +	git -C "$bazdir" rev-parse --abbrev-ref HEAD >actual &&
> +	test_cmp expect actual &&
> +	echo "bam" >expect &&
> +	git rev-parse --abbrev-ref HEAD >actual &&
> +	test_cmp expect actual &&
>  	rm -r bazdir &&
>  	git worktree prune
>  '
> diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh
> index 38b850c10ef..61a2342bc2c 100755
> --- a/t/t5605-clone-local.sh
> +++ b/t/t5605-clone-local.sh
> @@ -15,8 +15,12 @@ test_expect_success 'preparing origin repository' '
>  	: >file && git add . && git commit -m1 &&
>  	git clone --bare . a.git &&
>  	git clone --bare . x &&
> -	test "$(cd a.git && git config --bool core.bare)" = true &&
> -	test "$(cd x && git config --bool core.bare)" = true &&
> +	echo true >expect &&
> +	git -C a.git config --bool core.bare >actual &&
> +	test_cmp expect actual &&
> +	echo true >expect &&
> +	git -C x config --bool core.bare >actual &&
> +	test_cmp expect actual &&
>  	git bundle create b1.bundle --all &&
>  	git bundle create b2.bundle main &&
>  	mkdir dir &&
> @@ -28,9 +32,10 @@ test_expect_success 'preparing origin repository' '
>  
>  test_expect_success 'local clone without .git suffix' '
>  	git clone -l -s a b &&
> -	(cd b &&
> -	test "$(git config --bool core.bare)" = false &&
> -	git fetch)
> +	echo false >expect &&
> +	git -C b config --bool core.bare >actual &&
> +	test_cmp expect actual &&
> +	git -C b fetch
>  '
>  
>  test_expect_success 'local clone with .git suffix' '
> diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh
> index ebeca12a711..1927a862839 100755
> --- a/t/t7402-submodule-rebase.sh
> +++ b/t/t7402-submodule-rebase.sh
> @@ -82,11 +82,19 @@ test_expect_success 'stash with a dirty submodule' '
>  	CURRENT=$(cd submodule && git rev-parse HEAD) &&
>  	git stash &&
>  	test new != $(cat file) &&
> -	test submodule = $(git diff --name-only) &&
> -	test $CURRENT = $(cd submodule && git rev-parse HEAD) &&
> +	echo submodule >expect &&
> +	git diff --name-only >actual &&
> +	test_cmp expect actual &&
> +
> +	echo "$CURRENT" >expect &&
> +	git -C submodule rev-parse HEAD >actual &&
> +	test_cmp expect actual &&
> +
>  	git stash apply &&
>  	test new = $(cat file) &&
> -	test $CURRENT = $(cd submodule && git rev-parse HEAD)
> +	echo "$CURRENT" >expect &&
> +	git -C submodule rev-parse HEAD >actual &&
> +	test_cmp expect actual
>  
>  '

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v3 8/8] tests: don't lose mist "git" exit codes
  2022-12-04  0:40       ` Eric Sunshine
@ 2022-12-05  0:45         ` Junio C Hamano
  0 siblings, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-05  0:45 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Ævar Arnfjörð Bjarmason, git, René Scharfe,
	Torsten Bögershausen

Eric Sunshine <sunshine@sunshineco.com> writes:

> On Fri, Dec 2, 2022 at 6:53 AM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
>> tests: don't lose mist "git" exit codes
>
> "mist"?

s/t/c/ I thought.

In any case, it seems like 5,6,7,8/8 all are about using $(cmd) as
an argument to another command (as opposed to placing it on the
right side of a variable assignment) that loses the exit status of
running $(cmd), and it is a bit confusing which piece should go into
which one of these four.  It might make more sense to reorganize
these four steps along the file boundary.



^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell
  2022-12-02 10:02             ` Ævar Arnfjörð Bjarmason
@ 2022-12-07  6:09               ` Eric Sunshine
  0 siblings, 0 replies; 83+ messages in thread
From: Eric Sunshine @ 2022-12-07  6:09 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: Junio C Hamano, git, René Scharfe

On Fri, Dec 2, 2022 at 5:08 AM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
> On Fri, Dec 02 2022, Eric Sunshine wrote:
> > It might make more sense to turn this on its head and make it a
> > linting issue and simply throw a "?!FOO?!" as is done for other
> > suspect shell code. In fact, I already have local chainlint.pl patches
> > which detect whether a subshell is active so that the linter can
> > complain if it sees `cd` outside of a subshell. I would think that
> > warning about misuse of `exit 1` outside a subshell (and perhaps
> > `return 1` inside a subshell) should be possible, though I haven't
> > thought through all the possibilities.
>
> That would be great. As a reminder I think (maybe it's not what you have
> in mind exactly?) that we had a brief discussion on this topic starting
> at [1]. I.e. I was hoping chainlint.pl could be extended to detect
> exactly these sort of "test...$(git" patterns (among other things).

I recall it but haven't really put any additional thought into it. I
did put a little bit of thought into how to upgrade chainlint.pl to
supplant check-non-portable-shell.pl, though that doesn't help much
with your wish list. More recently, I've been thinking that it might
make more sense for chainlint.pl to generate an AST rather than
working against the raw token stream, which may mesh better with the
sort of rewriting you mentioned, and may simplify (or complexify) some
of the linting heuristics. I haven't really thought it through yet,
and I'm always concerned about slowing down the script too much -- but
perhaps I'm worrying unnecessarily if your Makefile-based
parallelization patches land, or if we just rip out parallelization
altogether as Peff was suggesting.

> This topic doesn't get us there, but once we finally get rid of some of
> those patterns it would be nice to have assertions to ensure they don't
> come back.

Ya.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [PATCH v4 0/6] tests: fix ignored & hidden exit codes
  2022-12-02 11:52   ` [PATCH v3 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
                       ` (7 preceding siblings ...)
  2022-12-02 11:52     ` [PATCH v3 8/8] tests: don't lose mist "git" exit codes Ævar Arnfjörð Bjarmason
@ 2022-12-19 10:19     ` Ævar Arnfjörð Bjarmason
  2022-12-19 10:19       ` [PATCH v4 1/6] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
                         ` (7 more replies)
  8 siblings, 8 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-19 10:19 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Various fixes for "git" on the LHS of a pipe, but mostly when in
"test" expressions like:

	test str = "$(git some-command)" &&

Changes since v3[1]:

 * The previous 1/8 and 3/8 were picked independently, and have landed
   on "master". I was waiting for those to graduate before a re-roll.
 * Add a missing test_expect_success to 1/6, as pointed out by René
   (thanks!).
 * Remove commit message mention of the now-dead test_cmp_cmd (thanks
   Eric!)
 * Reword commit messages, fix typos etc. (thanks Junio, and other
   reviewers!)

I think this should address all of the feedback on the v3, except
Junio's suggestion of perhaps re-arranging this series around file
boundaries.

Given the potential size of that range-diff I thought it was better to
mosttly keep the same structure.

1. https://lore.kernel.org/git/cover-v3-0.8-00000000000-20221202T114733Z-avarab@gmail.com/

Ævar Arnfjörð Bjarmason (6):
  auto-crlf tests: don't lose exit code in loops and outside tests
  t/lib-patch-mode.sh: fix ignored exit codes
  tests: don't lose exit status with "(cd ...; test <op> $(git ...))"
  tests: don't lose exit status with "test <op> $(git ...)"
  tests: don't lose "git" exit codes in "! ( git ... | grep )"
  tests: don't lose misc "git" exit codes

 t/lib-httpd.sh                     |   5 +-
 t/lib-patch-mode.sh                |  11 ++-
 t/lib-submodule-update.sh          |  26 ++++---
 t/t0001-init.sh                    |   9 ++-
 t/t0002-gitfile.sh                 |   4 +-
 t/t0027-auto-crlf.sh               |  66 ++++++++++--------
 t/t0055-beyond-symlinks.sh         |  14 +++-
 t/t0060-path-utils.sh              | 107 +++++++++++++++++++++--------
 t/t0100-previous.sh                |   8 ++-
 t/t1401-symbolic-ref.sh            |   3 +-
 t/t1504-ceiling-dirs.sh            |   8 ++-
 t/t2005-checkout-index-symlinks.sh |   8 ++-
 t/t3200-branch.sh                  |  13 ++--
 t/t3700-add.sh                     |  18 +++--
 t/t3701-add-interactive.sh         |   8 ++-
 t/t5522-pull-symlink.sh            |   4 +-
 t/t5605-clone-local.sh             |  15 ++--
 t/t7402-submodule-rebase.sh        |  23 +++++--
 t/t7504-commit-msg-hook.sh         |   4 +-
 t/t7516-commit-races.sh            |   3 +-
 t/t7810-grep.sh                    |   4 +-
 21 files changed, 243 insertions(+), 118 deletions(-)

Range-diff against v3:
1:  64dfec31fb3 < -:  ----------- merge tests: don't ignore "rev-parse" exit code in helper
2:  394d5e46494 ! 1:  68d276dd421 auto-crlf tests: don't lose exit code in loops and outside tests
    @@ t/t0027-auto-crlf.sh: commit_MIX_chkwrn () {
      	test_expect_success "commit file with mixed EOL onto LF crlf=$crlf attr=$attr" '
      		check_warning "$lfwarn" ${pfx}_LF.err
     @@ t/t0027-auto-crlf.sh: checkout_files () {
    + 	lfmixcrlf=$1 ; shift
    + 	lfmixcr=$1 ; shift
    + 	crlfnul=$1 ; shift
    +-	create_gitattributes "$attr" $ident $aeol &&
    +-	git config core.autocrlf $crlf &&
    ++	test_expect_success "setup config for checkout attr=$attr ident=$ident aeol=$aeol core.autocrlf=$crlf" '
    ++		create_gitattributes "$attr" $ident $aeol &&
    ++		git config core.autocrlf $crlf
    ++	'
      	pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
      	for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
      	do
3:  4ec075689f6 < -:  ----------- diff tests: fix ignored exit codes in t4023
4:  c080899dd5f ! 2:  d351075f0ab t/lib-patch-mode.sh: fix ignored exit codes
    @@ Commit message
         t/lib-patch-mode.sh: fix ignored exit codes
     
         Fix code added in b319ef70a94 (Add a small patch-mode testing library,
    -    2009-08-13) to use &&-chaining and the newly added "test_cmp_cmd".
    +    2009-08-13) to use &&-chaining.
    +
         This avoids losing both the exit code of a "git" and the "cat"
         processes.
     
    @@ Commit message
         SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
         discovered it while looking at leaks in related code.
     
    -    The "cat _head >expect" here is redundant, we could simply give
    -    "_head" to "test_cmp", but let's be consistent in using the "expect"
    -    and "actual" names for clarity.
    -
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## t/lib-patch-mode.sh ##
5:  58ac6fe5604 ! 3:  f5b2489609c tests: use "test_cmp" instead of "test" in sub-shells
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    tests: use "test_cmp" instead of "test" in sub-shells
    +    tests: don't lose exit status with "(cd ...; test <op> $(git ...))"
     
    -    Convert a few cases where we were using "test" inside a sub-shell, and
    -    were losing the exit code of "git".
    +    Rewrite tests that ran "git" inside command substitution and lost the
    +    exit status of "git" so that we notice the failing "git".
     
    -    In the case of "t3200-branch.sh" some adjacent code outside of a
    -    sub-shell that was losing the exit code is also being converted, as
    -    it's within the same hunk.
    +    Have them use modern patterns such as a "test_cmp" of the expected
    +    outputs instead, and avoid needlessly spawning sub-shell in favor of
    +    using "git -C <dir>".
    +
    +    We'll fix more of these these in the subsequent commit, for now we're
    +    only converting the cases where this loss of exit code was combined
    +    with spawning a sub-shell. The one exception to that is the casein
    +    "t3200-branch.sh" where adjacent code didn't use a sub-shell, let's
    +    convert that here as it's within the same hunk.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
6:  51f32b42ce6 ! 4:  da66e5bf1c1 tests: don't lose 'test <str> = $(cmd ...)"' exit code
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    tests: don't lose 'test <str> = $(cmd ...)"' exit code
    +    tests: don't lose exit status with "test <op> $(git ...)"
     
    -    Convert some cases in the test suite where we'd lose the exit code of
    -    a command being interpolated as one of the arguments to the "test"
    -    builtin function to use &&-chaining and "test_cmp" instead.
    -
    -    This way we won't lose the exit code, and the failure output will be
    -    more helpful.
    +    As with the preceding commit, rewrite tests that ran "git" inside
    +    command substitution and lost the exit status of "git" so that we
    +    notice the failing "git". This time around we're converting cases that
    +    didn't involve a containing sub-shell around the command substitution.
     
         In the case of "t0060-path-utils.sh" and
         "t2005-checkout-index-symlinks.sh" convert the relevant code to using
7:  307f25db831 ! 5:  9596702978e tests: don't lose "git" exit codes in "! ( git ... | grep )"
    @@ Commit message
         - In the case of "t0055-beyond-symlinks.sh" compare against the
           expected output instead.
     
    +      We could use the same pattern as in the "t3700-add.sh" below, doing
    +      so would have the advantage that if we added an earlier test we
    +      wouldn't need to adjust the "expect" output.
    +
    +      But as "t0055-beyond-symlinks.sh" is a small and focused test (less
    +      than 40 lines in total) let's use "test_cmp" instead.
    +
         - For "t3700-add.sh" use "sed -n" to print the expected "bad" part,
    -      and use "test_must_be_empty" to assert that it's not there.
    +      and use "test_must_be_empty" to assert that it's not there. If we used
    +      "grep" we'd get a non-zero exit code.
    +
    +      We could use "test_expect_code 1 grep", but this is more consistent
    +      with existing patterns in the test suite.
     
           We can also remove a repeated invocation of "git ls-files" for the
           last test that's being modified in that file, and search the
8:  37c75f4a097 ! 6:  94df7a1764e tests: don't lose mist "git" exit codes
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    tests: don't lose mist "git" exit codes
    +    tests: don't lose misc "git" exit codes
     
         Fix a few miscellaneous cases where:
     
-- 
2.39.0.1071.g97ce8966538


^ permalink raw reply	[flat|nested] 83+ messages in thread

* [PATCH v4 1/6] auto-crlf tests: don't lose exit code in loops and outside tests
  2022-12-19 10:19     ` [PATCH v4 0/6] tests: fix ignored & hidden " Ævar Arnfjörð Bjarmason
@ 2022-12-19 10:19       ` Ævar Arnfjörð Bjarmason
  2022-12-19 12:07         ` René Scharfe
  2022-12-19 10:19       ` [PATCH v4 2/6] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
                         ` (6 subsequent siblings)
  7 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-19 10:19 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Change the functions which are called from within
"test_expect_success" to add the "|| return 1" idiom to their
for-loops, so we won't lose the exit code of "cp", "git" etc.

Then for those setup functions that aren't called from a
"test_expect_success" we need to put the setup code in a
"test_expect_success" as well. It would not be enough to properly
&&-chain these, as the calling code is the top-level script itself. As
we don't run the tests with "set -e" we won't report failing commands
at the top-level.

The "checkout" part of this would miss memory leaks under
SANITIZE=leak, this code doesn't leak (the relevant "git checkout"
leak has been fixed), but in a past version of git we'd continue past
this failure under SANITIZE=leak when these invocations had errored
out, even under "--immediate".

Helped-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0027-auto-crlf.sh | 66 +++++++++++++++++++++++++-------------------
 1 file changed, 38 insertions(+), 28 deletions(-)

diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index a94ac1eae37..2f57c8669cb 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -70,7 +70,8 @@ create_NNO_MIX_files () {
 				cp CRLF        ${pfx}_CRLF.txt &&
 				cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
 				cp LF_mix_CR   ${pfx}_LF_mix_CR.txt &&
-				cp CRLF_nul    ${pfx}_CRLF_nul.txt
+				cp CRLF_nul    ${pfx}_CRLF_nul.txt ||
+				return 1
 			done
 		done
 	done
@@ -101,7 +102,8 @@ commit_check_warn () {
 	do
 		fname=${pfx}_$f.txt &&
 		cp $f $fname &&
-		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
+		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
+		return 1
 	done &&
 	git commit -m "core.autocrlf $crlf" &&
 	check_warning "$lfname" ${pfx}_LF.err &&
@@ -121,15 +123,19 @@ commit_chk_wrnNNO () {
 	lfmixcr=$1 ; shift
 	crlfnul=$1 ; shift
 	pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
-	#Commit files on top of existing file
-	create_gitattributes "$attr" $aeol &&
-	for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
-	do
-		fname=${pfx}_$f.txt &&
-		cp $f $fname &&
-		printf Z >>"$fname" &&
-		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
-	done
+
+	test_expect_success 'setup commit NNO files' '
+		#Commit files on top of existing file
+		create_gitattributes "$attr" $aeol &&
+		for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
+		do
+			fname=${pfx}_$f.txt &&
+			cp $f $fname &&
+			printf Z >>"$fname" &&
+			git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
+			return 1
+		done
+	'
 
 	test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" '
 		check_warning "$lfwarn" ${pfx}_LF.err
@@ -163,15 +169,19 @@ commit_MIX_chkwrn () {
 	lfmixcr=$1 ; shift
 	crlfnul=$1 ; shift
 	pfx=MIX_attr_${attr}_aeol_${aeol}_${crlf}
-	#Commit file with CLRF_mix_LF on top of existing file
-	create_gitattributes "$attr" $aeol &&
-	for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
-	do
-		fname=${pfx}_$f.txt &&
-		cp CRLF_mix_LF $fname &&
-		printf Z >>"$fname" &&
-		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
-	done
+
+	test_expect_success 'setup commit file with mixed EOL' '
+		#Commit file with CLRF_mix_LF on top of existing file
+		create_gitattributes "$attr" $aeol &&
+		for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
+		do
+			fname=${pfx}_$f.txt &&
+			cp CRLF_mix_LF $fname &&
+			printf Z >>"$fname" &&
+			git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
+			return 1
+		done
+	'
 
 	test_expect_success "commit file with mixed EOL onto LF crlf=$crlf attr=$attr" '
 		check_warning "$lfwarn" ${pfx}_LF.err
@@ -289,17 +299,17 @@ checkout_files () {
 	lfmixcrlf=$1 ; shift
 	lfmixcr=$1 ; shift
 	crlfnul=$1 ; shift
-	create_gitattributes "$attr" $ident $aeol &&
-	git config core.autocrlf $crlf &&
+	test_expect_success "setup config for checkout attr=$attr ident=$ident aeol=$aeol core.autocrlf=$crlf" '
+		create_gitattributes "$attr" $ident $aeol &&
+		git config core.autocrlf $crlf
+	'
 	pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
 	for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
 	do
-		rm crlf_false_attr__$f.txt &&
-		if test -z "$ceol"; then
-			git checkout -- crlf_false_attr__$f.txt
-		else
-			git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
-		fi
+		test_expect_success "setup $f checkout ${ceol:+ with -c core.eol=$ceol}"  '
+			rm -f crlf_false_attr__$f.txt &&
+			git ${ceol:+-c core.eol=$ceol} checkout -- crlf_false_attr__$f.txt
+		'
 	done
 
 	test_expect_success "ls-files --eol attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol" '
-- 
2.39.0.1071.g97ce8966538


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v4 2/6] t/lib-patch-mode.sh: fix ignored exit codes
  2022-12-19 10:19     ` [PATCH v4 0/6] tests: fix ignored & hidden " Ævar Arnfjörð Bjarmason
  2022-12-19 10:19       ` [PATCH v4 1/6] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
@ 2022-12-19 10:19       ` Ævar Arnfjörð Bjarmason
  2022-12-20  0:09         ` Junio C Hamano
  2022-12-27 16:40         ` Phillip Wood
  2022-12-19 10:19       ` [PATCH v4 3/6] tests: don't lose exit status with "(cd ...; test <op> $(git ...))" Ævar Arnfjörð Bjarmason
                         ` (5 subsequent siblings)
  7 siblings, 2 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-19 10:19 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Fix code added in b319ef70a94 (Add a small patch-mode testing library,
2009-08-13) to use &&-chaining.

This avoids losing both the exit code of a "git" and the "cat"
processes.

This fixes cases where we'd have e.g. missed memory leaks under
SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
discovered it while looking at leaks in related code.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-patch-mode.sh | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/t/lib-patch-mode.sh b/t/lib-patch-mode.sh
index cfd76bf987b..89ca1f78055 100644
--- a/t/lib-patch-mode.sh
+++ b/t/lib-patch-mode.sh
@@ -29,8 +29,12 @@ set_and_save_state () {
 
 # verify_state <path> <expected-worktree-content> <expected-index-content>
 verify_state () {
-	test "$(cat "$1")" = "$2" &&
-	test "$(git show :"$1")" = "$3"
+	echo "$2" >expect &&
+	test_cmp expect "$1" &&
+
+	echo "$3" >expect &&
+	git show :"$1" >actual &&
+	test_cmp expect actual
 }
 
 # verify_saved_state <path>
@@ -46,5 +50,6 @@ save_head () {
 }
 
 verify_saved_head () {
-	test "$(cat _head)" = "$(git rev-parse HEAD)"
+	git rev-parse HEAD >actual &&
+	test_cmp _head actual
 }
-- 
2.39.0.1071.g97ce8966538


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v4 3/6] tests: don't lose exit status with "(cd ...; test <op> $(git ...))"
  2022-12-19 10:19     ` [PATCH v4 0/6] tests: fix ignored & hidden " Ævar Arnfjörð Bjarmason
  2022-12-19 10:19       ` [PATCH v4 1/6] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
  2022-12-19 10:19       ` [PATCH v4 2/6] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
@ 2022-12-19 10:19       ` Ævar Arnfjörð Bjarmason
  2022-12-20  0:20         ` Junio C Hamano
  2022-12-19 10:19       ` [PATCH v4 4/6] tests: don't lose exit status with "test <op> $(git ...)" Ævar Arnfjörð Bjarmason
                         ` (4 subsequent siblings)
  7 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-19 10:19 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Rewrite tests that ran "git" inside command substitution and lost the
exit status of "git" so that we notice the failing "git".

Have them use modern patterns such as a "test_cmp" of the expected
outputs instead, and avoid needlessly spawning sub-shell in favor of
using "git -C <dir>".

We'll fix more of these these in the subsequent commit, for now we're
only converting the cases where this loss of exit code was combined
with spawning a sub-shell. The one exception to that is the casein
"t3200-branch.sh" where adjacent code didn't use a sub-shell, let's
convert that here as it's within the same hunk.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-httpd.sh              |  5 +++--
 t/lib-submodule-update.sh   | 22 +++++++++-------------
 t/t0060-path-utils.sh       |  4 +++-
 t/t3200-branch.sh           | 13 +++++++------
 t/t5605-clone-local.sh      | 15 ++++++++++-----
 t/t7402-submodule-rebase.sh | 14 +++++++++++---
 6 files changed, 43 insertions(+), 30 deletions(-)

diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index 608949ea80b..31e7fa3010c 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -217,8 +217,9 @@ test_http_push_nonff () {
 		git commit -a -m path2 --amend &&
 
 		test_must_fail git push -v origin >output 2>&1 &&
-		(cd "$REMOTE_REPO" &&
-		 test $HEAD = $(git rev-parse --verify HEAD))
+		echo "$HEAD" >expect &&
+		git -C "$REMOTE_REPO" rev-parse --verify HEAD >actual &&
+		test_cmp expect actual
 	'
 
 	test_expect_success 'non-fast-forward push show ref status' '
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 2d31fcfda1f..d7c2b670b4a 100644
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -168,20 +168,16 @@ replace_gitfile_with_git_dir () {
 # Note that this only supports submodules at the root level of the
 # superproject, with the default name, i.e. same as its path.
 test_git_directory_is_unchanged () {
-	(
-		cd ".git/modules/$1" &&
-		# does core.worktree point at the right place?
-		test "$(git config core.worktree)" = "../../../$1" &&
-		# remove it temporarily before comparing, as
-		# "$1/.git/config" lacks it...
-		git config --unset core.worktree
-	) &&
+	# does core.worktree point at the right place?
+	echo "../../../$1" >expect &&
+	git -C ".git/modules/$1" config core.worktree >actual &&
+	test_cmp expect actual &&
+	# remove it temporarily before comparing, as
+	# "$1/.git/config" lacks it...
+	git -C ".git/modules/$1" config --unset core.worktree &&
 	diff -r ".git/modules/$1" "$1/.git" &&
-	(
-		# ... and then restore.
-		cd ".git/modules/$1" &&
-		git config core.worktree "../../../$1"
-	)
+	# ... and then restore.
+	git -C ".git/modules/$1" config core.worktree "../../../$1"
 }
 
 test_git_directory_exists () {
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 68e29c904a6..53ec717cbca 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -255,7 +255,9 @@ test_expect_success 'prefix_path rejects absolute path to dir with same beginnin
 test_expect_success SYMLINKS 'prefix_path works with absolute path to a symlink to work tree having  same beginning as work tree' '
 	git init repo &&
 	ln -s repo repolink &&
-	test "a" = "$(cd repo && test-tool path-utils prefix_path prefix "$(pwd)/../repolink/a")"
+	echo "a" >expect &&
+	test-tool -C repo path-utils prefix_path prefix "$(cd repo && pwd)/../repolink/a" >actual &&
+	test_cmp expect actual
 '
 
 relative_path /foo/a/b/c/	/foo/a/b/	c/
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 5a169b68d6a..f5fbb84262b 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -242,12 +242,13 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
 test_expect_success 'git branch -M baz bam should succeed within a worktree in which baz is checked out' '
 	git checkout -b baz &&
 	git worktree add -f bazdir baz &&
-	(
-		cd bazdir &&
-		git branch -M baz bam &&
-		test $(git rev-parse --abbrev-ref HEAD) = bam
-	) &&
-	test $(git rev-parse --abbrev-ref HEAD) = bam &&
+	git -C "$bazdir" branch -M baz bam &&
+	echo "bam" >expect &&
+	git -C "$bazdir" rev-parse --abbrev-ref HEAD >actual &&
+	test_cmp expect actual &&
+	echo "bam" >expect &&
+	git rev-parse --abbrev-ref HEAD >actual &&
+	test_cmp expect actual &&
 	rm -r bazdir &&
 	git worktree prune
 '
diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh
index 38b850c10ef..61a2342bc2c 100755
--- a/t/t5605-clone-local.sh
+++ b/t/t5605-clone-local.sh
@@ -15,8 +15,12 @@ test_expect_success 'preparing origin repository' '
 	: >file && git add . && git commit -m1 &&
 	git clone --bare . a.git &&
 	git clone --bare . x &&
-	test "$(cd a.git && git config --bool core.bare)" = true &&
-	test "$(cd x && git config --bool core.bare)" = true &&
+	echo true >expect &&
+	git -C a.git config --bool core.bare >actual &&
+	test_cmp expect actual &&
+	echo true >expect &&
+	git -C x config --bool core.bare >actual &&
+	test_cmp expect actual &&
 	git bundle create b1.bundle --all &&
 	git bundle create b2.bundle main &&
 	mkdir dir &&
@@ -28,9 +32,10 @@ test_expect_success 'preparing origin repository' '
 
 test_expect_success 'local clone without .git suffix' '
 	git clone -l -s a b &&
-	(cd b &&
-	test "$(git config --bool core.bare)" = false &&
-	git fetch)
+	echo false >expect &&
+	git -C b config --bool core.bare >actual &&
+	test_cmp expect actual &&
+	git -C b fetch
 '
 
 test_expect_success 'local clone with .git suffix' '
diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh
index ebeca12a711..1927a862839 100755
--- a/t/t7402-submodule-rebase.sh
+++ b/t/t7402-submodule-rebase.sh
@@ -82,11 +82,19 @@ test_expect_success 'stash with a dirty submodule' '
 	CURRENT=$(cd submodule && git rev-parse HEAD) &&
 	git stash &&
 	test new != $(cat file) &&
-	test submodule = $(git diff --name-only) &&
-	test $CURRENT = $(cd submodule && git rev-parse HEAD) &&
+	echo submodule >expect &&
+	git diff --name-only >actual &&
+	test_cmp expect actual &&
+
+	echo "$CURRENT" >expect &&
+	git -C submodule rev-parse HEAD >actual &&
+	test_cmp expect actual &&
+
 	git stash apply &&
 	test new = $(cat file) &&
-	test $CURRENT = $(cd submodule && git rev-parse HEAD)
+	echo "$CURRENT" >expect &&
+	git -C submodule rev-parse HEAD >actual &&
+	test_cmp expect actual
 
 '
 
-- 
2.39.0.1071.g97ce8966538


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v4 4/6] tests: don't lose exit status with "test <op> $(git ...)"
  2022-12-19 10:19     ` [PATCH v4 0/6] tests: fix ignored & hidden " Ævar Arnfjörð Bjarmason
                         ` (2 preceding siblings ...)
  2022-12-19 10:19       ` [PATCH v4 3/6] tests: don't lose exit status with "(cd ...; test <op> $(git ...))" Ævar Arnfjörð Bjarmason
@ 2022-12-19 10:19       ` Ævar Arnfjörð Bjarmason
  2022-12-26  1:14         ` Junio C Hamano
  2022-12-19 10:19       ` [PATCH v4 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )" Ævar Arnfjörð Bjarmason
                         ` (3 subsequent siblings)
  7 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-19 10:19 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

As with the preceding commit, rewrite tests that ran "git" inside
command substitution and lost the exit status of "git" so that we
notice the failing "git". This time around we're converting cases that
didn't involve a containing sub-shell around the command substitution.

In the case of "t0060-path-utils.sh" and
"t2005-checkout-index-symlinks.sh" convert the relevant code to using
the modern style of indentation and newline wrapping while having to
change it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-submodule-update.sh          |   4 +-
 t/t0001-init.sh                    |   9 ++-
 t/t0002-gitfile.sh                 |   4 +-
 t/t0060-path-utils.sh              | 103 +++++++++++++++++++++--------
 t/t0100-previous.sh                |   8 ++-
 t/t1504-ceiling-dirs.sh            |   8 ++-
 t/t2005-checkout-index-symlinks.sh |   8 ++-
 t/t5522-pull-symlink.sh            |   4 +-
 t/t7402-submodule-rebase.sh        |   9 ++-
 t/t7504-commit-msg-hook.sh         |   4 +-
 t/t7810-grep.sh                    |   4 +-
 11 files changed, 120 insertions(+), 45 deletions(-)

diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index d7c2b670b4a..dee14992c52 100644
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -185,7 +185,9 @@ test_git_directory_exists () {
 	if test -f sub1/.git
 	then
 		# does core.worktree point at the right place?
-		test "$(git -C .git/modules/$1 config core.worktree)" = "../../../$1"
+		echo "../../../$1" >expect &&
+		git -C ".git/modules/$1" config core.worktree >actual &&
+		test_cmp expect actual
 	fi
 }
 
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index d479303efa0..30a6edca1d2 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -598,9 +598,14 @@ test_expect_success 'invalid default branch name' '
 test_expect_success 'branch -m with the initial branch' '
 	git init rename-initial &&
 	git -C rename-initial branch -m renamed &&
-	test renamed = $(git -C rename-initial symbolic-ref --short HEAD) &&
+	echo renamed >expect &&
+	git -C rename-initial symbolic-ref --short HEAD >actual &&
+	test_cmp expect actual &&
+
 	git -C rename-initial branch -m renamed again &&
-	test again = $(git -C rename-initial symbolic-ref --short HEAD)
+	echo again >expect &&
+	git -C rename-initial symbolic-ref --short HEAD >actual &&
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh
index 26eaca095a2..e013d38f485 100755
--- a/t/t0002-gitfile.sh
+++ b/t/t0002-gitfile.sh
@@ -33,7 +33,9 @@ test_expect_success 'bad setup: invalid .git file path' '
 
 test_expect_success 'final setup + check rev-parse --git-dir' '
 	echo "gitdir: $REAL" >.git &&
-	test "$REAL" = "$(git rev-parse --git-dir)"
+	echo "$REAL" >expect &&
+	git rev-parse --git-dir >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'check hash-object' '
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 53ec717cbca..6490ad5ca1b 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -10,20 +10,27 @@ TEST_PASSES_SANITIZE_LEAK=true
 
 norm_path() {
 	expected=$(test-tool path-utils print_path "$2")
-	test_expect_success $3 "normalize path: $1 => $2" \
-	"test \"\$(test-tool path-utils normalize_path_copy '$1')\" = '$expected'"
+	test_expect_success $3 "normalize path: $1 => $2" "
+		echo '$expected' >expect &&
+		test-tool path-utils normalize_path_copy '$1' >actual &&
+		test_cmp expect actual
+	"
 }
 
 relative_path() {
 	expected=$(test-tool path-utils print_path "$3")
-	test_expect_success $4 "relative path: $1 $2 => $3" \
-	"test \"\$(test-tool path-utils relative_path '$1' '$2')\" = '$expected'"
+	test_expect_success $4 "relative path: $1 $2 => $3" "
+		echo '$expected' >expect &&
+		test-tool path-utils relative_path '$1' '$2' >actual &&
+		test_cmp expect actual
+	"
 }
 
 test_submodule_relative_url() {
 	test_expect_success "test_submodule_relative_url: $1 $2 $3 => $4" "
-		actual=\$(test-tool submodule resolve-relative-url '$1' '$2' '$3') &&
-		test \"\$actual\" = '$4'
+		echo '$4' >expect &&
+		test-tool submodule resolve-relative-url '$1' '$2' '$3' >actual &&
+		test_cmp expect actual
 	"
 }
 
@@ -64,9 +71,11 @@ ancestor() {
 		expected=$(($expected-$rootslash+$rootoff))
 		;;
 	esac
-	test_expect_success $4 "longest ancestor: $1 $2 => $expected" \
-	"actual=\$(test-tool path-utils longest_ancestor_length '$1' '$2') &&
-	 test \"\$actual\" = '$expected'"
+	test_expect_success $4 "longest ancestor: $1 $2 => $expected" "
+		echo '$expected' >expect &&
+		test-tool path-utils longest_ancestor_length '$1' '$2' >actual &&
+		test_cmp expect actual
+	"
 }
 
 # Some absolute path tests should be skipped on Windows due to path mangling
@@ -166,8 +175,10 @@ ancestor D:/Users/me C:/ -1 MINGW
 ancestor //server/share/my-directory //server/share/ 14 MINGW
 
 test_expect_success 'strip_path_suffix' '
-	test c:/msysgit = $(test-tool path-utils strip_path_suffix \
-		c:/msysgit/libexec//git-core libexec/git-core)
+	echo c:/msysgit >expect &&
+	test-tool path-utils strip_path_suffix \
+		c:/msysgit/libexec//git-core libexec/git-core >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'absolute path rejects the empty string' '
@@ -188,35 +199,61 @@ test_expect_success 'real path rejects the empty string' '
 '
 
 test_expect_success POSIX 'real path works on absolute paths 1' '
+	echo / >expect &&
+	test-tool path-utils real_path "/" >actual &&
+	test_cmp expect actual &&
+
 	nopath="hopefully-absent-path" &&
-	test "/" = "$(test-tool path-utils real_path "/")" &&
-	test "/$nopath" = "$(test-tool path-utils real_path "/$nopath")"
+	echo "/$nopath" >expect &&
+	test-tool path-utils real_path "/$nopath" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'real path works on absolute paths 2' '
-	nopath="hopefully-absent-path" &&
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "$d")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "$d/$nopath")"
+	echo "$d" >expect &&
+	test-tool path-utils real_path "$d" >actual &&
+	test_cmp expect actual &&
+
+	nopath="hopefully-absent-path" &&
+	echo "$d/$nopath" >expect &&
+	test-tool path-utils real_path "$d/$nopath" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success POSIX 'real path removes extra leading slashes' '
+	echo "/" >expect &&
+	test-tool path-utils real_path "///" >actual &&
+	test_cmp expect actual &&
+
 	nopath="hopefully-absent-path" &&
-	test "/" = "$(test-tool path-utils real_path "///")" &&
-	test "/$nopath" = "$(test-tool path-utils real_path "///$nopath")" &&
+	echo "/$nopath" >expect &&
+	test-tool path-utils real_path "///$nopath" >actual &&
+	test_cmp expect actual &&
+
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "//$d")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "//$d/$nopath")"
+	echo "$d" >expect &&
+	test-tool path-utils real_path "//$d" >actual &&
+	test_cmp expect actual &&
+
+	echo "$d/$nopath" >expect &&
+	test-tool path-utils real_path "//$d/$nopath" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'real path removes other extra slashes' '
-	nopath="hopefully-absent-path" &&
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "$d///")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "$d///$nopath")"
+	echo "$d" >expect &&
+	test-tool path-utils real_path "$d///" >actual &&
+	test_cmp expect actual &&
+
+	nopath="hopefully-absent-path" &&
+	echo "$d/$nopath" >expect &&
+	test-tool path-utils real_path "$d///$nopath" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success SYMLINKS 'real path works on symlinks' '
@@ -227,19 +264,29 @@ test_expect_success SYMLINKS 'real path works on symlinks' '
 	mkdir third &&
 	dir="$(cd .git && pwd -P)" &&
 	dir2=third/../second/other/.git &&
-	test "$dir" = "$(test-tool path-utils real_path $dir2)" &&
+	echo "$dir" >expect &&
+	test-tool path-utils real_path $dir2 >actual &&
+	test_cmp expect actual &&
 	file="$dir"/index &&
-	test "$file" = "$(test-tool path-utils real_path $dir2/index)" &&
+	echo "$file" >expect &&
+	test-tool path-utils real_path $dir2/index >actual &&
+	test_cmp expect actual &&
 	basename=blub &&
-	test "$dir/$basename" = "$(cd .git && test-tool path-utils real_path "$basename")" &&
+	echo "$dir/$basename" >expect &&
+	test-tool -C .git path-utils real_path "$basename" >actual &&
+	test_cmp expect actual &&
 	ln -s ../first/file .git/syml &&
 	sym="$(cd first && pwd -P)"/file &&
-	test "$sym" = "$(test-tool path-utils real_path "$dir2/syml")"
+	echo "$sym" >expect &&
+	test-tool path-utils real_path "$dir2/syml" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success SYMLINKS 'prefix_path works with absolute paths to work tree symlinks' '
 	ln -s target symlink &&
-	test "$(test-tool path-utils prefix_path prefix "$(pwd)/symlink")" = "symlink"
+	echo "symlink" >expect &&
+	test-tool path-utils prefix_path prefix "$(pwd)/symlink" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'prefix_path works with only absolute path to work tree' '
diff --git a/t/t0100-previous.sh b/t/t0100-previous.sh
index a16cc3d2983..70a3223f219 100755
--- a/t/t0100-previous.sh
+++ b/t/t0100-previous.sh
@@ -12,7 +12,9 @@ test_expect_success 'branch -d @{-1}' '
 	test_commit A &&
 	git checkout -b junk &&
 	git checkout - &&
-	test "$(git symbolic-ref HEAD)" = refs/heads/main &&
+	echo refs/heads/main >expect &&
+	git symbolic-ref HEAD >actual &&
+	test_cmp expect actual &&
 	git branch -d @{-1} &&
 	test_must_fail git rev-parse --verify refs/heads/junk
 '
@@ -21,7 +23,9 @@ test_expect_success 'branch -d @{-12} when there is not enough switches yet' '
 	git reflog expire --expire=now &&
 	git checkout -b junk2 &&
 	git checkout - &&
-	test "$(git symbolic-ref HEAD)" = refs/heads/main &&
+	echo refs/heads/main >expect &&
+	git symbolic-ref HEAD >actual &&
+	test_cmp expect actual &&
 	test_must_fail git branch -d @{-12} &&
 	git rev-parse --verify refs/heads/main
 '
diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh
index 0fafcf9dde3..c1679e31d8a 100755
--- a/t/t1504-ceiling-dirs.sh
+++ b/t/t1504-ceiling-dirs.sh
@@ -6,8 +6,12 @@ TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_prefix() {
-	test_expect_success "$1" \
-	"test '$2' = \"\$(git rev-parse --show-prefix)\""
+	local expect="$2" &&
+	test_expect_success "$1: git rev-parse --show-prefix is '$2'" '
+		echo "$expect" >expect &&
+		git rev-parse --show-prefix >actual &&
+		test_cmp expect actual
+	'
 }
 
 test_fail() {
diff --git a/t/t2005-checkout-index-symlinks.sh b/t/t2005-checkout-index-symlinks.sh
index 112682a45a1..67d18cfa104 100755
--- a/t/t2005-checkout-index-symlinks.sh
+++ b/t/t2005-checkout-index-symlinks.sh
@@ -22,8 +22,10 @@ test_expect_success \
 git checkout-index symlink &&
 test -f symlink'
 
-test_expect_success \
-'the file must be the blob we added during the setup' '
-test "$(git hash-object -t blob symlink)" = $l'
+test_expect_success 'the file must be the blob we added during the setup' '
+	echo "$l" >expect &&
+	git hash-object -t blob symlink >actual &&
+	test_cmp expect actual
+'
 
 test_done
diff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh
index bcff460d0a2..9fb73a8c3eb 100755
--- a/t/t5522-pull-symlink.sh
+++ b/t/t5522-pull-symlink.sh
@@ -78,7 +78,9 @@ test_expect_success SYMLINKS 'pushing from symlinked subdir' '
 		git commit -m push ./file &&
 		git push
 	) &&
-	test push = $(git show HEAD:subdir/file)
+	echo push >expect &&
+	git show HEAD:subdir/file >actual &&
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh
index 1927a862839..c74798e8d24 100755
--- a/t/t7402-submodule-rebase.sh
+++ b/t/t7402-submodule-rebase.sh
@@ -55,12 +55,15 @@ chmod a+x fake-editor.sh
 
 test_expect_success 'interactive rebase with a dirty submodule' '
 
-	test submodule = $(git diff --name-only) &&
+	echo submodule >expect &&
+	git diff --name-only >actual &&
+	test_cmp expect actual &&
 	HEAD=$(git rev-parse HEAD) &&
 	GIT_EDITOR="\"$(pwd)/fake-editor.sh\"" EDITOR_TEXT="pick $HEAD" \
 		git rebase -i HEAD^ &&
-	test submodule = $(git diff --name-only)
-
+	echo submodule >expect &&
+	git diff --name-only >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'rebase with dirty file and submodule fails' '
diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh
index 07ca46fb0d5..d1255228d5f 100755
--- a/t/t7504-commit-msg-hook.sh
+++ b/t/t7504-commit-msg-hook.sh
@@ -102,7 +102,9 @@ test_expect_success 'setup: commit-msg hook that always fails' '
 '
 
 commit_msg_is () {
-	test "$(git log --pretty=format:%s%b -1)" = "$1"
+	printf "%s" "$1" >expect &&
+	git log --pretty=format:%s%b -1 >actual &&
+	test_cmp expect actual
 }
 
 test_expect_success 'with failing hook' '
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 8eded6ab274..39d6d713ecb 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -1001,7 +1001,9 @@ test_expect_success 'log --committer does not search in timestamp' '
 test_expect_success 'grep with CE_VALID file' '
 	git update-index --assume-unchanged t/t &&
 	rm t/t &&
-	test "$(git grep test)" = "t/t:test" &&
+	echo "t/t:test" >expect &&
+	git grep test >actual &&
+	test_cmp expect actual &&
 	git update-index --no-assume-unchanged t/t &&
 	git checkout t/t
 '
-- 
2.39.0.1071.g97ce8966538


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v4 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )"
  2022-12-19 10:19     ` [PATCH v4 0/6] tests: fix ignored & hidden " Ævar Arnfjörð Bjarmason
                         ` (3 preceding siblings ...)
  2022-12-19 10:19       ` [PATCH v4 4/6] tests: don't lose exit status with "test <op> $(git ...)" Ævar Arnfjörð Bjarmason
@ 2022-12-19 10:19       ` Ævar Arnfjörð Bjarmason
  2022-12-26  1:18         ` Junio C Hamano
  2022-12-27 16:44         ` Phillip Wood
  2022-12-19 10:19       ` [PATCH v4 6/6] tests: don't lose misc "git" exit codes Ævar Arnfjörð Bjarmason
                         ` (2 subsequent siblings)
  7 siblings, 2 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-19 10:19 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Change tests that would lose the "git" exit code via a negation
pattern to:

- In the case of "t0055-beyond-symlinks.sh" compare against the
  expected output instead.

  We could use the same pattern as in the "t3700-add.sh" below, doing
  so would have the advantage that if we added an earlier test we
  wouldn't need to adjust the "expect" output.

  But as "t0055-beyond-symlinks.sh" is a small and focused test (less
  than 40 lines in total) let's use "test_cmp" instead.

- For "t3700-add.sh" use "sed -n" to print the expected "bad" part,
  and use "test_must_be_empty" to assert that it's not there. If we used
  "grep" we'd get a non-zero exit code.

  We could use "test_expect_code 1 grep", but this is more consistent
  with existing patterns in the test suite.

  We can also remove a repeated invocation of "git ls-files" for the
  last test that's being modified in that file, and search the
  existing "files" output instead.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0055-beyond-symlinks.sh | 14 ++++++++++++--
 t/t3700-add.sh             | 18 +++++++++++++-----
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/t/t0055-beyond-symlinks.sh b/t/t0055-beyond-symlinks.sh
index 6bada370225..c3eb1158ef9 100755
--- a/t/t0055-beyond-symlinks.sh
+++ b/t/t0055-beyond-symlinks.sh
@@ -15,12 +15,22 @@ test_expect_success SYMLINKS setup '
 
 test_expect_success SYMLINKS 'update-index --add beyond symlinks' '
 	test_must_fail git update-index --add c/d &&
-	! ( git ls-files | grep c/d )
+	cat >expect <<-\EOF &&
+	a
+	b/d
+	EOF
+	git ls-files >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success SYMLINKS 'add beyond symlinks' '
 	test_must_fail git add c/d &&
-	! ( git ls-files | grep c/d )
+	cat >expect <<-\EOF &&
+	a
+	b/d
+	EOF
+	git ls-files >actual &&
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index 51afbd7b24a..82dd768944f 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -106,24 +106,32 @@ test_expect_success '.gitignore test setup' '
 
 test_expect_success '.gitignore is honored' '
 	git add . &&
-	! (git ls-files | grep "\\.ig")
+	git ls-files >files &&
+	sed -n "/\\.ig/p" <files >actual &&
+	test_must_be_empty actual
 '
 
 test_expect_success 'error out when attempting to add ignored ones without -f' '
 	test_must_fail git add a.?? &&
-	! (git ls-files | grep "\\.ig")
+	git ls-files >files &&
+	sed -n "/\\.ig/p" <files >actual &&
+	test_must_be_empty actual
 '
 
 test_expect_success 'error out when attempting to add ignored ones without -f' '
 	test_must_fail git add d.?? &&
-	! (git ls-files | grep "\\.ig")
+	git ls-files >files &&
+	sed -n "/\\.ig/p" <files >actual &&
+	test_must_be_empty actual
 '
 
 test_expect_success 'error out when attempting to add ignored ones but add others' '
 	touch a.if &&
 	test_must_fail git add a.?? &&
-	! (git ls-files | grep "\\.ig") &&
-	(git ls-files | grep a.if)
+	git ls-files >files &&
+	sed -n "/\\.ig/p" <files >actual &&
+	test_must_be_empty actual &&
+	grep a.if files
 '
 
 test_expect_success 'add ignored ones with -f' '
-- 
2.39.0.1071.g97ce8966538


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v4 6/6] tests: don't lose misc "git" exit codes
  2022-12-19 10:19     ` [PATCH v4 0/6] tests: fix ignored & hidden " Ævar Arnfjörð Bjarmason
                         ` (4 preceding siblings ...)
  2022-12-19 10:19       ` [PATCH v4 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )" Ævar Arnfjörð Bjarmason
@ 2022-12-19 10:19       ` Ævar Arnfjörð Bjarmason
  2022-12-27 16:46         ` Phillip Wood
  2022-12-20  0:06       ` [PATCH v4 0/6] tests: fix ignored & hidden " Junio C Hamano
  2023-02-06 22:44       ` [PATCH v5 " Ævar Arnfjörð Bjarmason
  7 siblings, 1 reply; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-19 10:19 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Ævar Arnfjörð Bjarmason

Fix a few miscellaneous cases where:

- We lost the "git" exit code via "git ... | grep"
- Likewise by having a $(git) argument to git itself
- Used "test -z" to check that a command emitted no output, we can use
  "test_must_be_empty" and &&-chaining instead.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1401-symbolic-ref.sh    | 3 ++-
 t/t3701-add-interactive.sh | 8 +++++---
 t/t7516-commit-races.sh    | 3 ++-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh
index d708acdb819..5e36899d207 100755
--- a/t/t1401-symbolic-ref.sh
+++ b/t/t1401-symbolic-ref.sh
@@ -33,7 +33,8 @@ test_expect_success 'symbolic-ref refuses non-ref for HEAD' '
 reset_to_sane
 
 test_expect_success 'symbolic-ref refuses bare sha1' '
-	test_must_fail git symbolic-ref HEAD $(git rev-parse HEAD)
+	rev=$(git rev-parse HEAD) &&
+	test_must_fail git symbolic-ref HEAD "$rev"
 '
 
 reset_to_sane
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 5841f280fb2..f1fe5d60677 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -296,9 +296,11 @@ test_expect_success FILEMODE 'stage mode and hunk' '
 	echo content >>file &&
 	chmod +x file &&
 	printf "y\\ny\\n" | git add -p &&
-	git diff --cached file | grep "new mode" &&
-	git diff --cached file | grep "+content" &&
-	test -z "$(git diff file)"
+	git diff --cached file >out &&
+	grep "new mode" out &&
+	grep "+content" out &&
+	git diff file >out &&
+	test_must_be_empty out
 '
 
 # end of tests disabled when filemode is not usable
diff --git a/t/t7516-commit-races.sh b/t/t7516-commit-races.sh
index f2ce14e9071..2d38a16480e 100755
--- a/t/t7516-commit-races.sh
+++ b/t/t7516-commit-races.sh
@@ -10,7 +10,8 @@ test_expect_success 'race to create orphan commit' '
 	test_must_fail env EDITOR=./hare-editor git commit --allow-empty -m tortoise -e &&
 	git show -s --pretty=format:%s >subject &&
 	grep hare subject &&
-	test -z "$(git show -s --pretty=format:%P)"
+	git show -s --pretty=format:%P >out &&
+	test_must_be_empty out
 '
 
 test_expect_success 'race to create non-orphan commit' '
-- 
2.39.0.1071.g97ce8966538


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 1/6] auto-crlf tests: don't lose exit code in loops and outside tests
  2022-12-19 10:19       ` [PATCH v4 1/6] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
@ 2022-12-19 12:07         ` René Scharfe
  0 siblings, 0 replies; 83+ messages in thread
From: René Scharfe @ 2022-12-19 12:07 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git
  Cc: Junio C Hamano, Eric Sunshine, Torsten Bögershausen

Am 19.12.22 um 11:19 schrieb Ævar Arnfjörð Bjarmason:
> Change the functions which are called from within
> "test_expect_success" to add the "|| return 1" idiom to their
> for-loops, so we won't lose the exit code of "cp", "git" etc.
>
> Then for those setup functions that aren't called from a
> "test_expect_success" we need to put the setup code in a
> "test_expect_success" as well. It would not be enough to properly
> &&-chain these, as the calling code is the top-level script itself. As
> we don't run the tests with "set -e" we won't report failing commands
> at the top-level.
>
> The "checkout" part of this would miss memory leaks under
> SANITIZE=leak, this code doesn't leak (the relevant "git checkout"
> leak has been fixed), but in a past version of git we'd continue past
> this failure under SANITIZE=leak when these invocations had errored
> out, even under "--immediate".
>
> Helped-by: René Scharfe <l.s.r@web.de>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t0027-auto-crlf.sh | 66 +++++++++++++++++++++++++-------------------
>  1 file changed, 38 insertions(+), 28 deletions(-)
>
> diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
> index a94ac1eae37..2f57c8669cb 100755
> --- a/t/t0027-auto-crlf.sh
> +++ b/t/t0027-auto-crlf.sh
> @@ -70,7 +70,8 @@ create_NNO_MIX_files () {
>  				cp CRLF        ${pfx}_CRLF.txt &&
>  				cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
>  				cp LF_mix_CR   ${pfx}_LF_mix_CR.txt &&
> -				cp CRLF_nul    ${pfx}_CRLF_nul.txt
> +				cp CRLF_nul    ${pfx}_CRLF_nul.txt ||
> +				return 1
>  			done
>  		done
>  	done
> @@ -101,7 +102,8 @@ commit_check_warn () {
>  	do
>  		fname=${pfx}_$f.txt &&
>  		cp $f $fname &&
> -		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
> +		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
> +		return 1
>  	done &&
>  	git commit -m "core.autocrlf $crlf" &&
>  	check_warning "$lfname" ${pfx}_LF.err &&
> @@ -121,15 +123,19 @@ commit_chk_wrnNNO () {
>  	lfmixcr=$1 ; shift
>  	crlfnul=$1 ; shift
>  	pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
> -	#Commit files on top of existing file
> -	create_gitattributes "$attr" $aeol &&
> -	for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
> -	do
> -		fname=${pfx}_$f.txt &&
> -		cp $f $fname &&
> -		printf Z >>"$fname" &&
> -		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
> -	done
> +
> +	test_expect_success 'setup commit NNO files' '
> +		#Commit files on top of existing file
> +		create_gitattributes "$attr" $aeol &&
> +		for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
> +		do
> +			fname=${pfx}_$f.txt &&
> +			cp $f $fname &&
> +			printf Z >>"$fname" &&
> +			git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
> +			return 1
> +		done
> +	'
>
>  	test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" '
>  		check_warning "$lfwarn" ${pfx}_LF.err
> @@ -163,15 +169,19 @@ commit_MIX_chkwrn () {
>  	lfmixcr=$1 ; shift
>  	crlfnul=$1 ; shift
>  	pfx=MIX_attr_${attr}_aeol_${aeol}_${crlf}
> -	#Commit file with CLRF_mix_LF on top of existing file
> -	create_gitattributes "$attr" $aeol &&
> -	for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
> -	do
> -		fname=${pfx}_$f.txt &&
> -		cp CRLF_mix_LF $fname &&
> -		printf Z >>"$fname" &&
> -		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
> -	done
> +
> +	test_expect_success 'setup commit file with mixed EOL' '
> +		#Commit file with CLRF_mix_LF on top of existing file
> +		create_gitattributes "$attr" $aeol &&
> +		for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
> +		do
> +			fname=${pfx}_$f.txt &&
> +			cp CRLF_mix_LF $fname &&
> +			printf Z >>"$fname" &&
> +			git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
> +			return 1
> +		done
> +	'
>
>  	test_expect_success "commit file with mixed EOL onto LF crlf=$crlf attr=$attr" '
>  		check_warning "$lfwarn" ${pfx}_LF.err
> @@ -289,17 +299,17 @@ checkout_files () {
>  	lfmixcrlf=$1 ; shift
>  	lfmixcr=$1 ; shift
>  	crlfnul=$1 ; shift
> -	create_gitattributes "$attr" $ident $aeol &&
> -	git config core.autocrlf $crlf &&
> +	test_expect_success "setup config for checkout attr=$attr ident=$ident aeol=$aeol core.autocrlf=$crlf" '
> +		create_gitattributes "$attr" $ident $aeol &&
> +		git config core.autocrlf $crlf
> +	'
>  	pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
>  	for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
>  	do
> -		rm crlf_false_attr__$f.txt &&
> -		if test -z "$ceol"; then
> -			git checkout -- crlf_false_attr__$f.txt
> -		else
> -			git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
> -		fi
> +		test_expect_success "setup $f checkout ${ceol:+ with -c core.eol=$ceol}"  '
> +			rm -f crlf_false_attr__$f.txt &&
> +			git ${ceol:+-c core.eol=$ceol} checkout -- crlf_false_attr__$f.txt
> +		'

OK, but why have test_expect_success inside the loop here, while a simlilar
loop is inside the two test_expect_success bodies above?  Do we really need
five invocations here instead of one?  It's just setup code.

>  	done
>
>  	test_expect_success "ls-files --eol attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol" '

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 0/6] tests: fix ignored & hidden exit codes
  2022-12-19 10:19     ` [PATCH v4 0/6] tests: fix ignored & hidden " Ævar Arnfjörð Bjarmason
                         ` (5 preceding siblings ...)
  2022-12-19 10:19       ` [PATCH v4 6/6] tests: don't lose misc "git" exit codes Ævar Arnfjörð Bjarmason
@ 2022-12-20  0:06       ` Junio C Hamano
  2023-02-06 22:44       ` [PATCH v5 " Ævar Arnfjörð Bjarmason
  7 siblings, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-20  0:06 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, René Scharfe, Eric Sunshine, Torsten Bögershausen

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> I think this should address all of the feedback on the v3, except
> Junio's suggestion of perhaps re-arranging this series around file
> boundaries.
>
> Given the potential size of that range-diff I thought it was better to
> mosttly keep the same structure.

Sorry, I do not recall making such a suggestion but if I did, it
probably was an indication that the group of patches I suggested
such a change were unreviewable as-is, and by definition range-diff
is irrelevant if that is the case (i.e. the part that was
unreviewable would be freshly reviewed with reorganization).

In any case, I think we have been seeing patches to unhide the exit
status from more individual command invocations, a theme this series
should fit well.  Thanks for working on it.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 2/6] t/lib-patch-mode.sh: fix ignored exit codes
  2022-12-19 10:19       ` [PATCH v4 2/6] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
@ 2022-12-20  0:09         ` Junio C Hamano
  2022-12-27 16:40         ` Phillip Wood
  1 sibling, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-20  0:09 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, René Scharfe, Eric Sunshine, Torsten Bögershausen

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Fix code added in b319ef70a94 (Add a small patch-mode testing library,
> 2009-08-13) to use &&-chaining.
>
> This avoids losing both the exit code of a "git" and the "cat"
> processes.
>
> This fixes cases where we'd have e.g. missed memory leaks under
> SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
> discovered it while looking at leaks in related code.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/lib-patch-mode.sh | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)

Looks quite sensible.

> diff --git a/t/lib-patch-mode.sh b/t/lib-patch-mode.sh
> index cfd76bf987b..89ca1f78055 100644
> --- a/t/lib-patch-mode.sh
> +++ b/t/lib-patch-mode.sh
> @@ -29,8 +29,12 @@ set_and_save_state () {
>  
>  # verify_state <path> <expected-worktree-content> <expected-index-content>
>  verify_state () {
> -	test "$(cat "$1")" = "$2" &&
> -	test "$(git show :"$1")" = "$3"
> +	echo "$2" >expect &&
> +	test_cmp expect "$1" &&
> +
> +	echo "$3" >expect &&
> +	git show :"$1" >actual &&
> +	test_cmp expect actual
>  }
>  
>  # verify_saved_state <path>
> @@ -46,5 +50,6 @@ save_head () {
>  }
>  
>  verify_saved_head () {
> -	test "$(cat _head)" = "$(git rev-parse HEAD)"
> +	git rev-parse HEAD >actual &&
> +	test_cmp _head actual
>  }

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 3/6] tests: don't lose exit status with "(cd ...; test <op> $(git ...))"
  2022-12-19 10:19       ` [PATCH v4 3/6] tests: don't lose exit status with "(cd ...; test <op> $(git ...))" Ævar Arnfjörð Bjarmason
@ 2022-12-20  0:20         ` Junio C Hamano
  0 siblings, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-20  0:20 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, René Scharfe, Eric Sunshine, Torsten Bögershausen

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> -	test "a" = "$(cd repo && test-tool path-utils prefix_path prefix "$(pwd)/../repolink/a")"
> +	echo "a" >expect &&
> +	test-tool -C repo path-utils prefix_path prefix "$(cd repo && pwd)/../repolink/a" >actual &&

If we fail to cd to 'repo', "$(cd repo && pwd)/../repolink/a" would
silently expand to nonsense, but presumably "test-tool -C repo"
would fail loudly in such a case, so we should be OK here?

> @@ -28,9 +32,10 @@ test_expect_success 'preparing origin repository' '
>  
>  test_expect_success 'local clone without .git suffix' '
>  	git clone -l -s a b &&
> -	(cd b &&
> -	test "$(git config --bool core.bare)" = false &&
> -	git fetch)
> +	echo false >expect &&
> +	git -C b config --bool core.bare >actual &&
> +	test_cmp expect actual &&
> +	git -C b fetch
>  '

I am not sure if the above with full of "git -C" is strictly an
improvement over

	(
		cd b &&
		echo false >expect &&
		git config --bool core.bare >actual &&
		test_cmp expect actual &&
		git fetch
	)

and even if it were, the reason why it is better would be vastly
different from the reason why it is better that we no longer do
"test $(cmd) = false".  I very much hate the pattern described on
the commit title of this step (which by definition this patch fixes
many instances of).  I.e.

	(cd ...; test <op> $(git ...))

might be something you find that needs improvements, but "don't lose
exit status" ONLY applies to the "test <op> $(git ...)" part, and
the other half, i.e. (cd ...), has nothing to do with "don't lose
exit status" badness.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 4/6] tests: don't lose exit status with "test <op> $(git ...)"
  2022-12-19 10:19       ` [PATCH v4 4/6] tests: don't lose exit status with "test <op> $(git ...)" Ævar Arnfjörð Bjarmason
@ 2022-12-26  1:14         ` Junio C Hamano
  0 siblings, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-26  1:14 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, René Scharfe, Eric Sunshine, Torsten Bögershausen

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> As with the preceding commit, rewrite tests that ran "git" inside
> command substitution and lost the exit status of "git" so that we
> notice the failing "git". This time around we're converting cases that
> didn't involve a containing sub-shell around the command substitution.
>
> In the case of "t0060-path-utils.sh" and
> "t2005-checkout-index-symlinks.sh" convert the relevant code to using
> the modern style of indentation and newline wrapping while having to
> change it.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---

Unlike the previous one, this looks sharply focused to deal with
having $(git ...) as one of the arguments to "test".  Looking good.


^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )"
  2022-12-19 10:19       ` [PATCH v4 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )" Ævar Arnfjörð Bjarmason
@ 2022-12-26  1:18         ` Junio C Hamano
  2022-12-27 16:44         ` Phillip Wood
  1 sibling, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-26  1:18 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, René Scharfe, Eric Sunshine, Torsten Bögershausen

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change tests that would lose the "git" exit code via a negation
> pattern to:

Looking good.  thanks.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 2/6] t/lib-patch-mode.sh: fix ignored exit codes
  2022-12-19 10:19       ` [PATCH v4 2/6] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
  2022-12-20  0:09         ` Junio C Hamano
@ 2022-12-27 16:40         ` Phillip Wood
  2022-12-27 18:14           ` Ævar Arnfjörð Bjarmason
  1 sibling, 1 reply; 83+ messages in thread
From: Phillip Wood @ 2022-12-27 16:40 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen

Hi Ævar

On 19/12/2022 10:19, Ævar Arnfjörð Bjarmason wrote:
> Fix code added in b319ef70a94 (Add a small patch-mode testing library,
> 2009-08-13) to use &&-chaining.
> 
> This avoids losing both the exit code of a "git" and the "cat"
> processes.
> 
> This fixes cases where we'd have e.g. missed memory leaks under
> SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
> discovered it while looking at leaks in related code.
> [...] 
>   # verify_saved_state <path>
> @@ -46,5 +50,6 @@ save_head () {
>   }
>   
>   verify_saved_head () {
> -	test "$(cat _head)" = "$(git rev-parse HEAD)"
> +	git rev-parse HEAD >actual &&
> +	test_cmp _head actual

Aren't these two lines are re-implementing test_cmp_rev()?

Best Wishes

Phillip


^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )"
  2022-12-19 10:19       ` [PATCH v4 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )" Ævar Arnfjörð Bjarmason
  2022-12-26  1:18         ` Junio C Hamano
@ 2022-12-27 16:44         ` Phillip Wood
  2022-12-27 17:13           ` Phillip Wood
  2022-12-27 23:16           ` Junio C Hamano
  1 sibling, 2 replies; 83+ messages in thread
From: Phillip Wood @ 2022-12-27 16:44 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen

Hi Ævar

On 19/12/2022 10:19, Ævar Arnfjörð Bjarmason wrote:
> Change tests that would lose the "git" exit code via a negation
> pattern to:
> 
> - In the case of "t0055-beyond-symlinks.sh" compare against the
>    expected output instead.
> 
>    We could use the same pattern as in the "t3700-add.sh" below, doing
>    so would have the advantage that if we added an earlier test we
>    wouldn't need to adjust the "expect" output.
> 
>    But as "t0055-beyond-symlinks.sh" is a small and focused test (less
>    than 40 lines in total) let's use "test_cmp" instead.
> 
> - For "t3700-add.sh" use "sed -n" to print the expected "bad" part,
>    and use "test_must_be_empty" to assert that it's not there. If we used
>    "grep" we'd get a non-zero exit code.
> 
>    We could use "test_expect_code 1 grep", but this is more consistent
>    with existing patterns in the test suite.

It seems strange to use sed here, you could just keep using grep and 
check the output is empty if you don't want to use test_expect_code. 
There is also no need to redirect the input of the sed commands.

Best Wishes

Phillip

>    We can also remove a repeated invocation of "git ls-files" for the
>    last test that's being modified in that file, and search the
>    existing "files" output instead.
> 
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>   t/t0055-beyond-symlinks.sh | 14 ++++++++++++--
>   t/t3700-add.sh             | 18 +++++++++++++-----
>   2 files changed, 25 insertions(+), 7 deletions(-)
> 
> diff --git a/t/t0055-beyond-symlinks.sh b/t/t0055-beyond-symlinks.sh
> index 6bada370225..c3eb1158ef9 100755
> --- a/t/t0055-beyond-symlinks.sh
> +++ b/t/t0055-beyond-symlinks.sh
> @@ -15,12 +15,22 @@ test_expect_success SYMLINKS setup '
>   
>   test_expect_success SYMLINKS 'update-index --add beyond symlinks' '
>   	test_must_fail git update-index --add c/d &&
> -	! ( git ls-files | grep c/d )
> +	cat >expect <<-\EOF &&
> +	a
> +	b/d
> +	EOF
> +	git ls-files >actual &&
> +	test_cmp expect actual
>   '
>   
>   test_expect_success SYMLINKS 'add beyond symlinks' '
>   	test_must_fail git add c/d &&
> -	! ( git ls-files | grep c/d )
> +	cat >expect <<-\EOF &&
> +	a
> +	b/d
> +	EOF
> +	git ls-files >actual &&
> +	test_cmp expect actual
>   '
>   
>   test_done
> diff --git a/t/t3700-add.sh b/t/t3700-add.sh
> index 51afbd7b24a..82dd768944f 100755
> --- a/t/t3700-add.sh
> +++ b/t/t3700-add.sh
> @@ -106,24 +106,32 @@ test_expect_success '.gitignore test setup' '
>   
>   test_expect_success '.gitignore is honored' '
>   	git add . &&
> -	! (git ls-files | grep "\\.ig")
> +	git ls-files >files &&
> +	sed -n "/\\.ig/p" <files >actual &&
> +	test_must_be_empty actual
>   '
>   
>   test_expect_success 'error out when attempting to add ignored ones without -f' '
>   	test_must_fail git add a.?? &&
> -	! (git ls-files | grep "\\.ig")
> +	git ls-files >files &&
> +	sed -n "/\\.ig/p" <files >actual &&
> +	test_must_be_empty actual
>   '
>   
>   test_expect_success 'error out when attempting to add ignored ones without -f' '
>   	test_must_fail git add d.?? &&
> -	! (git ls-files | grep "\\.ig")
> +	git ls-files >files &&
> +	sed -n "/\\.ig/p" <files >actual &&
> +	test_must_be_empty actual
>   '
>   
>   test_expect_success 'error out when attempting to add ignored ones but add others' '
>   	touch a.if &&
>   	test_must_fail git add a.?? &&
> -	! (git ls-files | grep "\\.ig") &&
> -	(git ls-files | grep a.if)
> +	git ls-files >files &&
> +	sed -n "/\\.ig/p" <files >actual &&
> +	test_must_be_empty actual &&
> +	grep a.if files
>   '
>   
>   test_expect_success 'add ignored ones with -f' '

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 6/6] tests: don't lose misc "git" exit codes
  2022-12-19 10:19       ` [PATCH v4 6/6] tests: don't lose misc "git" exit codes Ævar Arnfjörð Bjarmason
@ 2022-12-27 16:46         ` Phillip Wood
  2022-12-27 18:18           ` Ævar Arnfjörð Bjarmason
  2022-12-27 23:17           ` Junio C Hamano
  0 siblings, 2 replies; 83+ messages in thread
From: Phillip Wood @ 2022-12-27 16:46 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen

Hi Ævar

On 19/12/2022 10:19, Ævar Arnfjörð Bjarmason wrote:
> Fix a few miscellaneous cases where:
> 
> - We lost the "git" exit code via "git ... | grep"
> - Likewise by having a $(git) argument to git itself
> - Used "test -z" to check that a command emitted no output, we can use
>    "test_must_be_empty" and &&-chaining instead.
> 
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> [...]
> diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
> index 5841f280fb2..f1fe5d60677 100755
> --- a/t/t3701-add-interactive.sh
> +++ b/t/t3701-add-interactive.sh
> @@ -296,9 +296,11 @@ test_expect_success FILEMODE 'stage mode and hunk' '
>   	echo content >>file &&
>   	chmod +x file &&
>   	printf "y\\ny\\n" | git add -p &&
> -	git diff --cached file | grep "new mode" &&
> -	git diff --cached file | grep "+content" &&
> -	test -z "$(git diff file)"
> +	git diff --cached file >out &&
> +	grep "new mode" out &&
> +	grep "+content" out &&
> +	git diff file >out &&
> +	test_must_be_empty out

"git diff --exit-code file" would suffice here, we don't need to 
redirect the output and check that it is empty.

Best Wishes

Phillip

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )"
  2022-12-27 16:44         ` Phillip Wood
@ 2022-12-27 17:13           ` Phillip Wood
  2022-12-27 23:16           ` Junio C Hamano
  1 sibling, 0 replies; 83+ messages in thread
From: Phillip Wood @ 2022-12-27 17:13 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason, git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen

On 27/12/2022 16:44, Phillip Wood wrote:
> On 19/12/2022 10:19, Ævar Arnfjörð Bjarmason wrote:
>> - For "t3700-add.sh" use "sed -n" to print the expected "bad" part,
>>    and use "test_must_be_empty" to assert that it's not there. If we used
>>    "grep" we'd get a non-zero exit code.
>>
>>    We could use "test_expect_code 1 grep", but this is more consistent
>>    with existing patterns in the test suite.
> 
> It seems strange to use sed here, you could just keep using grep and 
> check the output is empty if you don't want to use test_expect_code.

Sorry ignore that, using 'sed -n' means we don't have to worry about the 
exit code.

> There is also no need to redirect the input of the sed commands.
> 
> Best Wishes
> 
> Phillip
> 
>>    We can also remove a repeated invocation of "git ls-files" for the
>>    last test that's being modified in that file, and search the
>>    existing "files" output instead.
>>
>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>> ---
>>   t/t0055-beyond-symlinks.sh | 14 ++++++++++++--
>>   t/t3700-add.sh             | 18 +++++++++++++-----
>>   2 files changed, 25 insertions(+), 7 deletions(-)
>>
>> diff --git a/t/t0055-beyond-symlinks.sh b/t/t0055-beyond-symlinks.sh
>> index 6bada370225..c3eb1158ef9 100755
>> --- a/t/t0055-beyond-symlinks.sh
>> +++ b/t/t0055-beyond-symlinks.sh
>> @@ -15,12 +15,22 @@ test_expect_success SYMLINKS setup '
>>   test_expect_success SYMLINKS 'update-index --add beyond symlinks' '
>>       test_must_fail git update-index --add c/d &&
>> -    ! ( git ls-files | grep c/d )
>> +    cat >expect <<-\EOF &&
>> +    a
>> +    b/d
>> +    EOF
>> +    git ls-files >actual &&
>> +    test_cmp expect actual
>>   '
>>   test_expect_success SYMLINKS 'add beyond symlinks' '
>>       test_must_fail git add c/d &&
>> -    ! ( git ls-files | grep c/d )
>> +    cat >expect <<-\EOF &&
>> +    a
>> +    b/d
>> +    EOF
>> +    git ls-files >actual &&
>> +    test_cmp expect actual
>>   '
>>   test_done
>> diff --git a/t/t3700-add.sh b/t/t3700-add.sh
>> index 51afbd7b24a..82dd768944f 100755
>> --- a/t/t3700-add.sh
>> +++ b/t/t3700-add.sh
>> @@ -106,24 +106,32 @@ test_expect_success '.gitignore test setup' '
>>   test_expect_success '.gitignore is honored' '
>>       git add . &&
>> -    ! (git ls-files | grep "\\.ig")
>> +    git ls-files >files &&
>> +    sed -n "/\\.ig/p" <files >actual &&
>> +    test_must_be_empty actual
>>   '
>>   test_expect_success 'error out when attempting to add ignored ones 
>> without -f' '
>>       test_must_fail git add a.?? &&
>> -    ! (git ls-files | grep "\\.ig")
>> +    git ls-files >files &&
>> +    sed -n "/\\.ig/p" <files >actual &&
>> +    test_must_be_empty actual
>>   '
>>   test_expect_success 'error out when attempting to add ignored ones 
>> without -f' '
>>       test_must_fail git add d.?? &&
>> -    ! (git ls-files | grep "\\.ig")
>> +    git ls-files >files &&
>> +    sed -n "/\\.ig/p" <files >actual &&
>> +    test_must_be_empty actual
>>   '
>>   test_expect_success 'error out when attempting to add ignored ones 
>> but add others' '
>>       touch a.if &&
>>       test_must_fail git add a.?? &&
>> -    ! (git ls-files | grep "\\.ig") &&
>> -    (git ls-files | grep a.if)
>> +    git ls-files >files &&
>> +    sed -n "/\\.ig/p" <files >actual &&
>> +    test_must_be_empty actual &&
>> +    grep a.if files
>>   '
>>   test_expect_success 'add ignored ones with -f' '

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 2/6] t/lib-patch-mode.sh: fix ignored exit codes
  2022-12-27 16:40         ` Phillip Wood
@ 2022-12-27 18:14           ` Ævar Arnfjörð Bjarmason
  0 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-27 18:14 UTC (permalink / raw)
  To: phillip.wood
  Cc: git, Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen


On Tue, Dec 27 2022, Phillip Wood wrote:

> Hi Ævar
>
> On 19/12/2022 10:19, Ævar Arnfjörð Bjarmason wrote:
>> Fix code added in b319ef70a94 (Add a small patch-mode testing library,
>> 2009-08-13) to use &&-chaining.
>> This avoids losing both the exit code of a "git" and the "cat"
>> processes.
>> This fixes cases where we'd have e.g. missed memory leaks under
>> SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
>> discovered it while looking at leaks in related code.
>> [...]   # verify_saved_state <path>
>> @@ -46,5 +50,6 @@ save_head () {
>>   }
>>     verify_saved_head () {
>> -	test "$(cat _head)" = "$(git rev-parse HEAD)"
>> +	git rev-parse HEAD >actual &&
>> +	test_cmp _head actual
>
> Aren't these two lines are re-implementing test_cmp_rev()?

It does --verify, and this does not.

Could we use it? Yes, but I wanted to narrowly focus on just fixing the
lost exit codes in this series. Once you start to untangle "save_head"
and "verify_saved_head" you'll see that whether we narrowly used a
helper here or not isn't the only thing we could improve.

But such an improvement would make use use --verify, and we'd then want
to use that "--verify" for the earlier saved_head too, etc.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 6/6] tests: don't lose misc "git" exit codes
  2022-12-27 16:46         ` Phillip Wood
@ 2022-12-27 18:18           ` Ævar Arnfjörð Bjarmason
  2022-12-27 23:17           ` Junio C Hamano
  1 sibling, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2022-12-27 18:18 UTC (permalink / raw)
  To: phillip.wood
  Cc: git, Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen


On Tue, Dec 27 2022, Phillip Wood wrote:

> Hi Ævar
>
> On 19/12/2022 10:19, Ævar Arnfjörð Bjarmason wrote:
>> Fix a few miscellaneous cases where:
>> - We lost the "git" exit code via "git ... | grep"
>> - Likewise by having a $(git) argument to git itself
>> - Used "test -z" to check that a command emitted no output, we can use
>>    "test_must_be_empty" and &&-chaining instead.
>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>> [...]
>> diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
>> index 5841f280fb2..f1fe5d60677 100755
>> --- a/t/t3701-add-interactive.sh
>> +++ b/t/t3701-add-interactive.sh
>> @@ -296,9 +296,11 @@ test_expect_success FILEMODE 'stage mode and hunk' '
>>   	echo content >>file &&
>>   	chmod +x file &&
>>   	printf "y\\ny\\n" | git add -p &&
>> -	git diff --cached file | grep "new mode" &&
>> -	git diff --cached file | grep "+content" &&
>> -	test -z "$(git diff file)"
>> +	git diff --cached file >out &&
>> +	grep "new mode" out &&
>> +	grep "+content" out &&
>> +	git diff file >out &&
>> +	test_must_be_empty out
>
> "git diff --exit-code file" would suffice here, we don't need to
> redirect the output and check that it is empty.

Correct.

Or even "git diff-files -s --exit-code", which might make things clearer
still, or have this use the "diff_cmp" helper defined in the test file,
as most of its siblings do.

But as with a sibling comment of mine I wanted to avoid starting to
refactoring these tests for general betterment, and just to narrowly
avoid losing the exit code.


^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )"
  2022-12-27 16:44         ` Phillip Wood
  2022-12-27 17:13           ` Phillip Wood
@ 2022-12-27 23:16           ` Junio C Hamano
  1 sibling, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-27 23:16 UTC (permalink / raw)
  To: Phillip Wood
  Cc: Ævar Arnfjörð Bjarmason, git, René Scharfe,
	Eric Sunshine, Torsten Bögershausen

Phillip Wood <phillip.wood123@gmail.com> writes:

> It seems strange to use sed here, you could just keep using grep and
> check the output is empty if you don't want to use
> test_expect_code.

I am not sure what you mean by test_expect_code, but we can do the
"! grep -e pattern file" to ensure that the unwanted pattern does
not exist.  Unlike our command, we do not worry about system "grep"
being buggy, so if it yields non-zero, it is because no line in the
file matches the pattern.  After all, that is what the original code
fixed by this patch wanted to check.

The "do not lose exit code of the git command" part of the goal is
achieved by breaking the pipeline already, and we can keep the test
that uses grep.

Having said that, switching to "sed" is not too bad.  If we wanted
to expect N lines that matches the pattern in the file, with grep,
we need to do "! grep" dance when (and only when) N is zero.  With
sed, we do not have to worry about it.

> There is also no need to redirect the input of the
> sed commands.

That's true.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* Re: [PATCH v4 6/6] tests: don't lose misc "git" exit codes
  2022-12-27 16:46         ` Phillip Wood
  2022-12-27 18:18           ` Ævar Arnfjörð Bjarmason
@ 2022-12-27 23:17           ` Junio C Hamano
  1 sibling, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2022-12-27 23:17 UTC (permalink / raw)
  To: Phillip Wood
  Cc: Ævar Arnfjörð Bjarmason, git, René Scharfe,
	Eric Sunshine, Torsten Bögershausen

Phillip Wood <phillip.wood123@gmail.com> writes:

>> -	test -z "$(git diff file)"
>> ...
>> +	git diff file >out &&
>> +	test_must_be_empty out
>
> "git diff --exit-code file" would suffice here, we don't need to
> redirect the output and check that it is empty.

Yes, but the test is trying to be faithful to not just the intent
but also the implementation of the original, I think.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [PATCH v5 0/6] tests: fix ignored & hidden exit codes
  2022-12-19 10:19     ` [PATCH v4 0/6] tests: fix ignored & hidden " Ævar Arnfjörð Bjarmason
                         ` (6 preceding siblings ...)
  2022-12-20  0:06       ` [PATCH v4 0/6] tests: fix ignored & hidden " Junio C Hamano
@ 2023-02-06 22:44       ` Ævar Arnfjörð Bjarmason
  2023-02-06 22:44         ` [PATCH v5 1/6] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
                           ` (6 more replies)
  7 siblings, 7 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2023-02-06 22:44 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Phillip Wood,
	Ævar Arnfjörð Bjarmason

Various fixes for "git" on the LHS of a pipe, but mostly when in
"test" expressions like:

       test str = "$(git some-command)" &&

Changes since v4[1]:

 * Tried to address all outstanding concernse, some with commit
   message clarifications, others with code changes.
 * The main code change here is to avoid converting code adjacent to
   the fixed "test" code away from sub-shell use, per Junio's request.

Branch & CI for this at:
https://github.com/avar/git/tree/avar/fix-even-more-broken-test-code-hiding-failures-5

1. https://lore.kernel.org/git/cover-v4-0.6-00000000000-20221219T101240Z-avarab@gmail.com/

Ævar Arnfjörð Bjarmason (6):
  auto-crlf tests: don't lose exit code in loops and outside tests
  t/lib-patch-mode.sh: fix ignored exit codes
  tests: don't lose exit status with "(cd ...; test <op> $(git ...))"
  tests: don't lose exit status with "test <op> $(git ...)"
  tests: don't lose "git" exit codes in "! ( git ... | grep )"
  tests: don't lose misc "git" exit codes

 t/lib-httpd.sh                     |   8 ++-
 t/lib-patch-mode.sh                |  11 ++-
 t/lib-submodule-update.sh          |  26 ++++---
 t/t0001-init.sh                    |   9 ++-
 t/t0002-gitfile.sh                 |   4 +-
 t/t0027-auto-crlf.sh               |  66 ++++++++++--------
 t/t0055-beyond-symlinks.sh         |  14 +++-
 t/t0060-path-utils.sh              | 108 +++++++++++++++++++++--------
 t/t0100-previous.sh                |   8 ++-
 t/t1401-symbolic-ref.sh            |   3 +-
 t/t1504-ceiling-dirs.sh            |   8 ++-
 t/t2005-checkout-index-symlinks.sh |   8 ++-
 t/t3200-branch.sh                  |   8 ++-
 t/t3700-add.sh                     |  18 +++--
 t/t3701-add-interactive.sh         |   8 ++-
 t/t5522-pull-symlink.sh            |   4 +-
 t/t5605-clone-local.sh             |  12 +++-
 t/t7402-submodule-rebase.sh        |  23 ++++--
 t/t7504-commit-msg-hook.sh         |   4 +-
 t/t7516-commit-races.sh            |   3 +-
 t/t7810-grep.sh                    |   4 +-
 21 files changed, 245 insertions(+), 112 deletions(-)

Range-diff against v4:
1:  68d276dd421 ! 1:  66d0f91e6aa auto-crlf tests: don't lose exit code in loops and outside tests
    @@ Commit message
         this failure under SANITIZE=leak when these invocations had errored
         out, even under "--immediate".
     
    +    For checkout_files() we could run one test_expect_success() instead of
    +    the 5 we run now in a loop.
    +
    +    But as this function added in [1] is already taking pains to split up
    +    its setup into phases (there are 5 more "test_expect_success()" at the
    +    end of it already, see [1]), let's follow that existing convention.
    +
    +    1. 343151dcbdf (t0027: combinations of core.autocrlf, core.eol and text, 2014-06-29)
    +
         Helped-by: René Scharfe <l.s.r@web.de>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
2:  d351075f0ab ! 2:  97f8b6a7b86 t/lib-patch-mode.sh: fix ignored exit codes
    @@ Commit message
         SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
         discovered it while looking at leaks in related code.
     
    +    For "verify_saved_head()" we could make use of "test_cmp_rev" with
    +    some changes, but it uses "git rev-parse --verify", and this existing
    +    test does not. I think it could safely use it, but let's avoid the
    +    while-at-it change, and narrowly fix the exit code problem.
    +
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## t/lib-patch-mode.sh ##
3:  f5b2489609c ! 3:  d8f4c4a6d9e tests: don't lose exit status with "(cd ...; test <op> $(git ...))"
    @@ Commit message
         exit status of "git" so that we notice the failing "git".
     
         Have them use modern patterns such as a "test_cmp" of the expected
    -    outputs instead, and avoid needlessly spawning sub-shell in favor of
    -    using "git -C <dir>".
    +    outputs instead.
     
         We'll fix more of these these in the subsequent commit, for now we're
         only converting the cases where this loss of exit code was combined
    -    with spawning a sub-shell. The one exception to that is the casein
    -    "t3200-branch.sh" where adjacent code didn't use a sub-shell, let's
    -    convert that here as it's within the same hunk.
    +    with spawning a sub-shell.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ t/lib-httpd.sh: test_http_push_nonff () {
      		test_must_fail git push -v origin >output 2>&1 &&
     -		(cd "$REMOTE_REPO" &&
     -		 test $HEAD = $(git rev-parse --verify HEAD))
    -+		echo "$HEAD" >expect &&
    -+		git -C "$REMOTE_REPO" rev-parse --verify HEAD >actual &&
    -+		test_cmp expect actual
    ++		(
    ++			cd "$REMOTE_REPO" &&
    ++			echo "$HEAD" >expect &&
    ++			git rev-parse --verify HEAD >actual &&
    ++			test_cmp expect actual
    ++		)
      	'
      
      	test_expect_success 'non-fast-forward push show ref status' '
    @@ t/t0060-path-utils.sh: test_expect_success 'prefix_path rejects absolute path to
      	ln -s repo repolink &&
     -	test "a" = "$(cd repo && test-tool path-utils prefix_path prefix "$(pwd)/../repolink/a")"
     +	echo "a" >expect &&
    -+	test-tool -C repo path-utils prefix_path prefix "$(cd repo && pwd)/../repolink/a" >actual &&
    ++	repo_path="$(cd repo && pwd)" &&
    ++	test-tool -C repo path-utils prefix_path prefix "$repo_path/../repolink/a" >actual &&
     +	test_cmp expect actual
      '
      
      relative_path /foo/a/b/c/	/foo/a/b/	c/
     
      ## t/t3200-branch.sh ##
    -@@ t/t3200-branch.sh: test_expect_success 'git branch -M baz bam should succeed when baz is checked ou
    - test_expect_success 'git branch -M baz bam should succeed within a worktree in which baz is checked out' '
    - 	git checkout -b baz &&
    - 	git worktree add -f bazdir baz &&
    --	(
    --		cd bazdir &&
    --		git branch -M baz bam &&
    +@@ t/t3200-branch.sh: test_expect_success 'git branch -M baz bam should succeed within a worktree in w
    + 	(
    + 		cd bazdir &&
    + 		git branch -M baz bam &&
     -		test $(git rev-parse --abbrev-ref HEAD) = bam
    --	) &&
    ++		echo bam >expect &&
    ++		git rev-parse --abbrev-ref HEAD >actual &&
    ++		test_cmp expect actual
    + 	) &&
     -	test $(git rev-parse --abbrev-ref HEAD) = bam &&
    -+	git -C "$bazdir" branch -M baz bam &&
    -+	echo "bam" >expect &&
    -+	git -C "$bazdir" rev-parse --abbrev-ref HEAD >actual &&
    -+	test_cmp expect actual &&
    -+	echo "bam" >expect &&
    ++	echo bam >expect &&
     +	git rev-parse --abbrev-ref HEAD >actual &&
     +	test_cmp expect actual &&
      	rm -r bazdir &&
    @@ t/t5605-clone-local.sh: test_expect_success 'preparing origin repository' '
      	git bundle create b2.bundle main &&
      	mkdir dir &&
     @@ t/t5605-clone-local.sh: test_expect_success 'preparing origin repository' '
    - 
      test_expect_success 'local clone without .git suffix' '
      	git clone -l -s a b &&
    --	(cd b &&
    + 	(cd b &&
     -	test "$(git config --bool core.bare)" = false &&
    --	git fetch)
     +	echo false >expect &&
    -+	git -C b config --bool core.bare >actual &&
    ++	git config --bool core.bare >actual &&
     +	test_cmp expect actual &&
    -+	git -C b fetch
    + 	git fetch)
      '
      
    - test_expect_success 'local clone with .git suffix' '
     
      ## t/t7402-submodule-rebase.sh ##
     @@ t/t7402-submodule-rebase.sh: test_expect_success 'stash with a dirty submodule' '
4:  da66e5bf1c1 = 4:  e6f56478b65 tests: don't lose exit status with "test <op> $(git ...)"
5:  9596702978e = 5:  55abdbef49f tests: don't lose "git" exit codes in "! ( git ... | grep )"
6:  94df7a1764e = 6:  e7f10c0641a tests: don't lose misc "git" exit codes
-- 
2.39.1.1425.gac85d95d48c


^ permalink raw reply	[flat|nested] 83+ messages in thread

* [PATCH v5 1/6] auto-crlf tests: don't lose exit code in loops and outside tests
  2023-02-06 22:44       ` [PATCH v5 " Ævar Arnfjörð Bjarmason
@ 2023-02-06 22:44         ` Ævar Arnfjörð Bjarmason
  2023-02-06 22:44         ` [PATCH v5 2/6] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
                           ` (5 subsequent siblings)
  6 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2023-02-06 22:44 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Phillip Wood,
	Ævar Arnfjörð Bjarmason

Change the functions which are called from within
"test_expect_success" to add the "|| return 1" idiom to their
for-loops, so we won't lose the exit code of "cp", "git" etc.

Then for those setup functions that aren't called from a
"test_expect_success" we need to put the setup code in a
"test_expect_success" as well. It would not be enough to properly
&&-chain these, as the calling code is the top-level script itself. As
we don't run the tests with "set -e" we won't report failing commands
at the top-level.

The "checkout" part of this would miss memory leaks under
SANITIZE=leak, this code doesn't leak (the relevant "git checkout"
leak has been fixed), but in a past version of git we'd continue past
this failure under SANITIZE=leak when these invocations had errored
out, even under "--immediate".

For checkout_files() we could run one test_expect_success() instead of
the 5 we run now in a loop.

But as this function added in [1] is already taking pains to split up
its setup into phases (there are 5 more "test_expect_success()" at the
end of it already, see [1]), let's follow that existing convention.

1. 343151dcbdf (t0027: combinations of core.autocrlf, core.eol and text, 2014-06-29)

Helped-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0027-auto-crlf.sh | 66 +++++++++++++++++++++++++-------------------
 1 file changed, 38 insertions(+), 28 deletions(-)

diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index a94ac1eae37..2f57c8669cb 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -70,7 +70,8 @@ create_NNO_MIX_files () {
 				cp CRLF        ${pfx}_CRLF.txt &&
 				cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
 				cp LF_mix_CR   ${pfx}_LF_mix_CR.txt &&
-				cp CRLF_nul    ${pfx}_CRLF_nul.txt
+				cp CRLF_nul    ${pfx}_CRLF_nul.txt ||
+				return 1
 			done
 		done
 	done
@@ -101,7 +102,8 @@ commit_check_warn () {
 	do
 		fname=${pfx}_$f.txt &&
 		cp $f $fname &&
-		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
+		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
+		return 1
 	done &&
 	git commit -m "core.autocrlf $crlf" &&
 	check_warning "$lfname" ${pfx}_LF.err &&
@@ -121,15 +123,19 @@ commit_chk_wrnNNO () {
 	lfmixcr=$1 ; shift
 	crlfnul=$1 ; shift
 	pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
-	#Commit files on top of existing file
-	create_gitattributes "$attr" $aeol &&
-	for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
-	do
-		fname=${pfx}_$f.txt &&
-		cp $f $fname &&
-		printf Z >>"$fname" &&
-		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
-	done
+
+	test_expect_success 'setup commit NNO files' '
+		#Commit files on top of existing file
+		create_gitattributes "$attr" $aeol &&
+		for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
+		do
+			fname=${pfx}_$f.txt &&
+			cp $f $fname &&
+			printf Z >>"$fname" &&
+			git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
+			return 1
+		done
+	'
 
 	test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" '
 		check_warning "$lfwarn" ${pfx}_LF.err
@@ -163,15 +169,19 @@ commit_MIX_chkwrn () {
 	lfmixcr=$1 ; shift
 	crlfnul=$1 ; shift
 	pfx=MIX_attr_${attr}_aeol_${aeol}_${crlf}
-	#Commit file with CLRF_mix_LF on top of existing file
-	create_gitattributes "$attr" $aeol &&
-	for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
-	do
-		fname=${pfx}_$f.txt &&
-		cp CRLF_mix_LF $fname &&
-		printf Z >>"$fname" &&
-		git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
-	done
+
+	test_expect_success 'setup commit file with mixed EOL' '
+		#Commit file with CLRF_mix_LF on top of existing file
+		create_gitattributes "$attr" $aeol &&
+		for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
+		do
+			fname=${pfx}_$f.txt &&
+			cp CRLF_mix_LF $fname &&
+			printf Z >>"$fname" &&
+			git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err" ||
+			return 1
+		done
+	'
 
 	test_expect_success "commit file with mixed EOL onto LF crlf=$crlf attr=$attr" '
 		check_warning "$lfwarn" ${pfx}_LF.err
@@ -289,17 +299,17 @@ checkout_files () {
 	lfmixcrlf=$1 ; shift
 	lfmixcr=$1 ; shift
 	crlfnul=$1 ; shift
-	create_gitattributes "$attr" $ident $aeol &&
-	git config core.autocrlf $crlf &&
+	test_expect_success "setup config for checkout attr=$attr ident=$ident aeol=$aeol core.autocrlf=$crlf" '
+		create_gitattributes "$attr" $ident $aeol &&
+		git config core.autocrlf $crlf
+	'
 	pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
 	for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
 	do
-		rm crlf_false_attr__$f.txt &&
-		if test -z "$ceol"; then
-			git checkout -- crlf_false_attr__$f.txt
-		else
-			git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
-		fi
+		test_expect_success "setup $f checkout ${ceol:+ with -c core.eol=$ceol}"  '
+			rm -f crlf_false_attr__$f.txt &&
+			git ${ceol:+-c core.eol=$ceol} checkout -- crlf_false_attr__$f.txt
+		'
 	done
 
 	test_expect_success "ls-files --eol attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol" '
-- 
2.39.1.1425.gac85d95d48c


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v5 2/6] t/lib-patch-mode.sh: fix ignored exit codes
  2023-02-06 22:44       ` [PATCH v5 " Ævar Arnfjörð Bjarmason
  2023-02-06 22:44         ` [PATCH v5 1/6] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
@ 2023-02-06 22:44         ` Ævar Arnfjörð Bjarmason
  2023-02-06 22:44         ` [PATCH v5 3/6] tests: don't lose exit status with "(cd ...; test <op> $(git ...))" Ævar Arnfjörð Bjarmason
                           ` (4 subsequent siblings)
  6 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2023-02-06 22:44 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Phillip Wood,
	Ævar Arnfjörð Bjarmason

Fix code added in b319ef70a94 (Add a small patch-mode testing library,
2009-08-13) to use &&-chaining.

This avoids losing both the exit code of a "git" and the "cat"
processes.

This fixes cases where we'd have e.g. missed memory leaks under
SANITIZE=leak, this code doesn't leak now as far as I can tell, but I
discovered it while looking at leaks in related code.

For "verify_saved_head()" we could make use of "test_cmp_rev" with
some changes, but it uses "git rev-parse --verify", and this existing
test does not. I think it could safely use it, but let's avoid the
while-at-it change, and narrowly fix the exit code problem.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-patch-mode.sh | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/t/lib-patch-mode.sh b/t/lib-patch-mode.sh
index cfd76bf987b..89ca1f78055 100644
--- a/t/lib-patch-mode.sh
+++ b/t/lib-patch-mode.sh
@@ -29,8 +29,12 @@ set_and_save_state () {
 
 # verify_state <path> <expected-worktree-content> <expected-index-content>
 verify_state () {
-	test "$(cat "$1")" = "$2" &&
-	test "$(git show :"$1")" = "$3"
+	echo "$2" >expect &&
+	test_cmp expect "$1" &&
+
+	echo "$3" >expect &&
+	git show :"$1" >actual &&
+	test_cmp expect actual
 }
 
 # verify_saved_state <path>
@@ -46,5 +50,6 @@ save_head () {
 }
 
 verify_saved_head () {
-	test "$(cat _head)" = "$(git rev-parse HEAD)"
+	git rev-parse HEAD >actual &&
+	test_cmp _head actual
 }
-- 
2.39.1.1425.gac85d95d48c


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v5 3/6] tests: don't lose exit status with "(cd ...; test <op> $(git ...))"
  2023-02-06 22:44       ` [PATCH v5 " Ævar Arnfjörð Bjarmason
  2023-02-06 22:44         ` [PATCH v5 1/6] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
  2023-02-06 22:44         ` [PATCH v5 2/6] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
@ 2023-02-06 22:44         ` Ævar Arnfjörð Bjarmason
  2023-02-06 22:44         ` [PATCH v5 4/6] tests: don't lose exit status with "test <op> $(git ...)" Ævar Arnfjörð Bjarmason
                           ` (3 subsequent siblings)
  6 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2023-02-06 22:44 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Phillip Wood,
	Ævar Arnfjörð Bjarmason

Rewrite tests that ran "git" inside command substitution and lost the
exit status of "git" so that we notice the failing "git".

Have them use modern patterns such as a "test_cmp" of the expected
outputs instead.

We'll fix more of these these in the subsequent commit, for now we're
only converting the cases where this loss of exit code was combined
with spawning a sub-shell.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-httpd.sh              |  8 ++++++--
 t/lib-submodule-update.sh   | 22 +++++++++-------------
 t/t0060-path-utils.sh       |  5 ++++-
 t/t3200-branch.sh           |  8 ++++++--
 t/t5605-clone-local.sh      | 12 +++++++++---
 t/t7402-submodule-rebase.sh | 14 +++++++++++---
 6 files changed, 45 insertions(+), 24 deletions(-)

diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index 608949ea80b..b8b1d044e8b 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -217,8 +217,12 @@ test_http_push_nonff () {
 		git commit -a -m path2 --amend &&
 
 		test_must_fail git push -v origin >output 2>&1 &&
-		(cd "$REMOTE_REPO" &&
-		 test $HEAD = $(git rev-parse --verify HEAD))
+		(
+			cd "$REMOTE_REPO" &&
+			echo "$HEAD" >expect &&
+			git rev-parse --verify HEAD >actual &&
+			test_cmp expect actual
+		)
 	'
 
 	test_expect_success 'non-fast-forward push show ref status' '
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 2d31fcfda1f..d7c2b670b4a 100644
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -168,20 +168,16 @@ replace_gitfile_with_git_dir () {
 # Note that this only supports submodules at the root level of the
 # superproject, with the default name, i.e. same as its path.
 test_git_directory_is_unchanged () {
-	(
-		cd ".git/modules/$1" &&
-		# does core.worktree point at the right place?
-		test "$(git config core.worktree)" = "../../../$1" &&
-		# remove it temporarily before comparing, as
-		# "$1/.git/config" lacks it...
-		git config --unset core.worktree
-	) &&
+	# does core.worktree point at the right place?
+	echo "../../../$1" >expect &&
+	git -C ".git/modules/$1" config core.worktree >actual &&
+	test_cmp expect actual &&
+	# remove it temporarily before comparing, as
+	# "$1/.git/config" lacks it...
+	git -C ".git/modules/$1" config --unset core.worktree &&
 	diff -r ".git/modules/$1" "$1/.git" &&
-	(
-		# ... and then restore.
-		cd ".git/modules/$1" &&
-		git config core.worktree "../../../$1"
-	)
+	# ... and then restore.
+	git -C ".git/modules/$1" config core.worktree "../../../$1"
 }
 
 test_git_directory_exists () {
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 68e29c904a6..dcc78fb6a7b 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -255,7 +255,10 @@ test_expect_success 'prefix_path rejects absolute path to dir with same beginnin
 test_expect_success SYMLINKS 'prefix_path works with absolute path to a symlink to work tree having  same beginning as work tree' '
 	git init repo &&
 	ln -s repo repolink &&
-	test "a" = "$(cd repo && test-tool path-utils prefix_path prefix "$(pwd)/../repolink/a")"
+	echo "a" >expect &&
+	repo_path="$(cd repo && pwd)" &&
+	test-tool -C repo path-utils prefix_path prefix "$repo_path/../repolink/a" >actual &&
+	test_cmp expect actual
 '
 
 relative_path /foo/a/b/c/	/foo/a/b/	c/
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 5a169b68d6a..5a8a48287c1 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -245,9 +245,13 @@ test_expect_success 'git branch -M baz bam should succeed within a worktree in w
 	(
 		cd bazdir &&
 		git branch -M baz bam &&
-		test $(git rev-parse --abbrev-ref HEAD) = bam
+		echo bam >expect &&
+		git rev-parse --abbrev-ref HEAD >actual &&
+		test_cmp expect actual
 	) &&
-	test $(git rev-parse --abbrev-ref HEAD) = bam &&
+	echo bam >expect &&
+	git rev-parse --abbrev-ref HEAD >actual &&
+	test_cmp expect actual &&
 	rm -r bazdir &&
 	git worktree prune
 '
diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh
index 38b850c10ef..1d7b1abda1a 100755
--- a/t/t5605-clone-local.sh
+++ b/t/t5605-clone-local.sh
@@ -15,8 +15,12 @@ test_expect_success 'preparing origin repository' '
 	: >file && git add . && git commit -m1 &&
 	git clone --bare . a.git &&
 	git clone --bare . x &&
-	test "$(cd a.git && git config --bool core.bare)" = true &&
-	test "$(cd x && git config --bool core.bare)" = true &&
+	echo true >expect &&
+	git -C a.git config --bool core.bare >actual &&
+	test_cmp expect actual &&
+	echo true >expect &&
+	git -C x config --bool core.bare >actual &&
+	test_cmp expect actual &&
 	git bundle create b1.bundle --all &&
 	git bundle create b2.bundle main &&
 	mkdir dir &&
@@ -29,7 +33,9 @@ test_expect_success 'preparing origin repository' '
 test_expect_success 'local clone without .git suffix' '
 	git clone -l -s a b &&
 	(cd b &&
-	test "$(git config --bool core.bare)" = false &&
+	echo false >expect &&
+	git config --bool core.bare >actual &&
+	test_cmp expect actual &&
 	git fetch)
 '
 
diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh
index ebeca12a711..1927a862839 100755
--- a/t/t7402-submodule-rebase.sh
+++ b/t/t7402-submodule-rebase.sh
@@ -82,11 +82,19 @@ test_expect_success 'stash with a dirty submodule' '
 	CURRENT=$(cd submodule && git rev-parse HEAD) &&
 	git stash &&
 	test new != $(cat file) &&
-	test submodule = $(git diff --name-only) &&
-	test $CURRENT = $(cd submodule && git rev-parse HEAD) &&
+	echo submodule >expect &&
+	git diff --name-only >actual &&
+	test_cmp expect actual &&
+
+	echo "$CURRENT" >expect &&
+	git -C submodule rev-parse HEAD >actual &&
+	test_cmp expect actual &&
+
 	git stash apply &&
 	test new = $(cat file) &&
-	test $CURRENT = $(cd submodule && git rev-parse HEAD)
+	echo "$CURRENT" >expect &&
+	git -C submodule rev-parse HEAD >actual &&
+	test_cmp expect actual
 
 '
 
-- 
2.39.1.1425.gac85d95d48c


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v5 4/6] tests: don't lose exit status with "test <op> $(git ...)"
  2023-02-06 22:44       ` [PATCH v5 " Ævar Arnfjörð Bjarmason
                           ` (2 preceding siblings ...)
  2023-02-06 22:44         ` [PATCH v5 3/6] tests: don't lose exit status with "(cd ...; test <op> $(git ...))" Ævar Arnfjörð Bjarmason
@ 2023-02-06 22:44         ` Ævar Arnfjörð Bjarmason
  2023-02-06 22:44         ` [PATCH v5 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )" Ævar Arnfjörð Bjarmason
                           ` (2 subsequent siblings)
  6 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2023-02-06 22:44 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Phillip Wood,
	Ævar Arnfjörð Bjarmason

As with the preceding commit, rewrite tests that ran "git" inside
command substitution and lost the exit status of "git" so that we
notice the failing "git". This time around we're converting cases that
didn't involve a containing sub-shell around the command substitution.

In the case of "t0060-path-utils.sh" and
"t2005-checkout-index-symlinks.sh" convert the relevant code to using
the modern style of indentation and newline wrapping while having to
change it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-submodule-update.sh          |   4 +-
 t/t0001-init.sh                    |   9 ++-
 t/t0002-gitfile.sh                 |   4 +-
 t/t0060-path-utils.sh              | 103 +++++++++++++++++++++--------
 t/t0100-previous.sh                |   8 ++-
 t/t1504-ceiling-dirs.sh            |   8 ++-
 t/t2005-checkout-index-symlinks.sh |   8 ++-
 t/t5522-pull-symlink.sh            |   4 +-
 t/t7402-submodule-rebase.sh        |   9 ++-
 t/t7504-commit-msg-hook.sh         |   4 +-
 t/t7810-grep.sh                    |   4 +-
 11 files changed, 120 insertions(+), 45 deletions(-)

diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index d7c2b670b4a..dee14992c52 100644
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -185,7 +185,9 @@ test_git_directory_exists () {
 	if test -f sub1/.git
 	then
 		# does core.worktree point at the right place?
-		test "$(git -C .git/modules/$1 config core.worktree)" = "../../../$1"
+		echo "../../../$1" >expect &&
+		git -C ".git/modules/$1" config core.worktree >actual &&
+		test_cmp expect actual
 	fi
 }
 
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index d479303efa0..30a6edca1d2 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -598,9 +598,14 @@ test_expect_success 'invalid default branch name' '
 test_expect_success 'branch -m with the initial branch' '
 	git init rename-initial &&
 	git -C rename-initial branch -m renamed &&
-	test renamed = $(git -C rename-initial symbolic-ref --short HEAD) &&
+	echo renamed >expect &&
+	git -C rename-initial symbolic-ref --short HEAD >actual &&
+	test_cmp expect actual &&
+
 	git -C rename-initial branch -m renamed again &&
-	test again = $(git -C rename-initial symbolic-ref --short HEAD)
+	echo again >expect &&
+	git -C rename-initial symbolic-ref --short HEAD >actual &&
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh
index 26eaca095a2..e013d38f485 100755
--- a/t/t0002-gitfile.sh
+++ b/t/t0002-gitfile.sh
@@ -33,7 +33,9 @@ test_expect_success 'bad setup: invalid .git file path' '
 
 test_expect_success 'final setup + check rev-parse --git-dir' '
 	echo "gitdir: $REAL" >.git &&
-	test "$REAL" = "$(git rev-parse --git-dir)"
+	echo "$REAL" >expect &&
+	git rev-parse --git-dir >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'check hash-object' '
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index dcc78fb6a7b..0afa3d0d312 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -10,20 +10,27 @@ TEST_PASSES_SANITIZE_LEAK=true
 
 norm_path() {
 	expected=$(test-tool path-utils print_path "$2")
-	test_expect_success $3 "normalize path: $1 => $2" \
-	"test \"\$(test-tool path-utils normalize_path_copy '$1')\" = '$expected'"
+	test_expect_success $3 "normalize path: $1 => $2" "
+		echo '$expected' >expect &&
+		test-tool path-utils normalize_path_copy '$1' >actual &&
+		test_cmp expect actual
+	"
 }
 
 relative_path() {
 	expected=$(test-tool path-utils print_path "$3")
-	test_expect_success $4 "relative path: $1 $2 => $3" \
-	"test \"\$(test-tool path-utils relative_path '$1' '$2')\" = '$expected'"
+	test_expect_success $4 "relative path: $1 $2 => $3" "
+		echo '$expected' >expect &&
+		test-tool path-utils relative_path '$1' '$2' >actual &&
+		test_cmp expect actual
+	"
 }
 
 test_submodule_relative_url() {
 	test_expect_success "test_submodule_relative_url: $1 $2 $3 => $4" "
-		actual=\$(test-tool submodule resolve-relative-url '$1' '$2' '$3') &&
-		test \"\$actual\" = '$4'
+		echo '$4' >expect &&
+		test-tool submodule resolve-relative-url '$1' '$2' '$3' >actual &&
+		test_cmp expect actual
 	"
 }
 
@@ -64,9 +71,11 @@ ancestor() {
 		expected=$(($expected-$rootslash+$rootoff))
 		;;
 	esac
-	test_expect_success $4 "longest ancestor: $1 $2 => $expected" \
-	"actual=\$(test-tool path-utils longest_ancestor_length '$1' '$2') &&
-	 test \"\$actual\" = '$expected'"
+	test_expect_success $4 "longest ancestor: $1 $2 => $expected" "
+		echo '$expected' >expect &&
+		test-tool path-utils longest_ancestor_length '$1' '$2' >actual &&
+		test_cmp expect actual
+	"
 }
 
 # Some absolute path tests should be skipped on Windows due to path mangling
@@ -166,8 +175,10 @@ ancestor D:/Users/me C:/ -1 MINGW
 ancestor //server/share/my-directory //server/share/ 14 MINGW
 
 test_expect_success 'strip_path_suffix' '
-	test c:/msysgit = $(test-tool path-utils strip_path_suffix \
-		c:/msysgit/libexec//git-core libexec/git-core)
+	echo c:/msysgit >expect &&
+	test-tool path-utils strip_path_suffix \
+		c:/msysgit/libexec//git-core libexec/git-core >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'absolute path rejects the empty string' '
@@ -188,35 +199,61 @@ test_expect_success 'real path rejects the empty string' '
 '
 
 test_expect_success POSIX 'real path works on absolute paths 1' '
+	echo / >expect &&
+	test-tool path-utils real_path "/" >actual &&
+	test_cmp expect actual &&
+
 	nopath="hopefully-absent-path" &&
-	test "/" = "$(test-tool path-utils real_path "/")" &&
-	test "/$nopath" = "$(test-tool path-utils real_path "/$nopath")"
+	echo "/$nopath" >expect &&
+	test-tool path-utils real_path "/$nopath" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'real path works on absolute paths 2' '
-	nopath="hopefully-absent-path" &&
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "$d")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "$d/$nopath")"
+	echo "$d" >expect &&
+	test-tool path-utils real_path "$d" >actual &&
+	test_cmp expect actual &&
+
+	nopath="hopefully-absent-path" &&
+	echo "$d/$nopath" >expect &&
+	test-tool path-utils real_path "$d/$nopath" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success POSIX 'real path removes extra leading slashes' '
+	echo "/" >expect &&
+	test-tool path-utils real_path "///" >actual &&
+	test_cmp expect actual &&
+
 	nopath="hopefully-absent-path" &&
-	test "/" = "$(test-tool path-utils real_path "///")" &&
-	test "/$nopath" = "$(test-tool path-utils real_path "///$nopath")" &&
+	echo "/$nopath" >expect &&
+	test-tool path-utils real_path "///$nopath" >actual &&
+	test_cmp expect actual &&
+
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "//$d")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "//$d/$nopath")"
+	echo "$d" >expect &&
+	test-tool path-utils real_path "//$d" >actual &&
+	test_cmp expect actual &&
+
+	echo "$d/$nopath" >expect &&
+	test-tool path-utils real_path "//$d/$nopath" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'real path removes other extra slashes' '
-	nopath="hopefully-absent-path" &&
 	# Find an existing top-level directory for the remaining tests:
 	d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-	test "$d" = "$(test-tool path-utils real_path "$d///")" &&
-	test "$d/$nopath" = "$(test-tool path-utils real_path "$d///$nopath")"
+	echo "$d" >expect &&
+	test-tool path-utils real_path "$d///" >actual &&
+	test_cmp expect actual &&
+
+	nopath="hopefully-absent-path" &&
+	echo "$d/$nopath" >expect &&
+	test-tool path-utils real_path "$d///$nopath" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success SYMLINKS 'real path works on symlinks' '
@@ -227,19 +264,29 @@ test_expect_success SYMLINKS 'real path works on symlinks' '
 	mkdir third &&
 	dir="$(cd .git && pwd -P)" &&
 	dir2=third/../second/other/.git &&
-	test "$dir" = "$(test-tool path-utils real_path $dir2)" &&
+	echo "$dir" >expect &&
+	test-tool path-utils real_path $dir2 >actual &&
+	test_cmp expect actual &&
 	file="$dir"/index &&
-	test "$file" = "$(test-tool path-utils real_path $dir2/index)" &&
+	echo "$file" >expect &&
+	test-tool path-utils real_path $dir2/index >actual &&
+	test_cmp expect actual &&
 	basename=blub &&
-	test "$dir/$basename" = "$(cd .git && test-tool path-utils real_path "$basename")" &&
+	echo "$dir/$basename" >expect &&
+	test-tool -C .git path-utils real_path "$basename" >actual &&
+	test_cmp expect actual &&
 	ln -s ../first/file .git/syml &&
 	sym="$(cd first && pwd -P)"/file &&
-	test "$sym" = "$(test-tool path-utils real_path "$dir2/syml")"
+	echo "$sym" >expect &&
+	test-tool path-utils real_path "$dir2/syml" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success SYMLINKS 'prefix_path works with absolute paths to work tree symlinks' '
 	ln -s target symlink &&
-	test "$(test-tool path-utils prefix_path prefix "$(pwd)/symlink")" = "symlink"
+	echo "symlink" >expect &&
+	test-tool path-utils prefix_path prefix "$(pwd)/symlink" >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'prefix_path works with only absolute path to work tree' '
diff --git a/t/t0100-previous.sh b/t/t0100-previous.sh
index a16cc3d2983..70a3223f219 100755
--- a/t/t0100-previous.sh
+++ b/t/t0100-previous.sh
@@ -12,7 +12,9 @@ test_expect_success 'branch -d @{-1}' '
 	test_commit A &&
 	git checkout -b junk &&
 	git checkout - &&
-	test "$(git symbolic-ref HEAD)" = refs/heads/main &&
+	echo refs/heads/main >expect &&
+	git symbolic-ref HEAD >actual &&
+	test_cmp expect actual &&
 	git branch -d @{-1} &&
 	test_must_fail git rev-parse --verify refs/heads/junk
 '
@@ -21,7 +23,9 @@ test_expect_success 'branch -d @{-12} when there is not enough switches yet' '
 	git reflog expire --expire=now &&
 	git checkout -b junk2 &&
 	git checkout - &&
-	test "$(git symbolic-ref HEAD)" = refs/heads/main &&
+	echo refs/heads/main >expect &&
+	git symbolic-ref HEAD >actual &&
+	test_cmp expect actual &&
 	test_must_fail git branch -d @{-12} &&
 	git rev-parse --verify refs/heads/main
 '
diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh
index 0fafcf9dde3..c1679e31d8a 100755
--- a/t/t1504-ceiling-dirs.sh
+++ b/t/t1504-ceiling-dirs.sh
@@ -6,8 +6,12 @@ TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_prefix() {
-	test_expect_success "$1" \
-	"test '$2' = \"\$(git rev-parse --show-prefix)\""
+	local expect="$2" &&
+	test_expect_success "$1: git rev-parse --show-prefix is '$2'" '
+		echo "$expect" >expect &&
+		git rev-parse --show-prefix >actual &&
+		test_cmp expect actual
+	'
 }
 
 test_fail() {
diff --git a/t/t2005-checkout-index-symlinks.sh b/t/t2005-checkout-index-symlinks.sh
index 112682a45a1..67d18cfa104 100755
--- a/t/t2005-checkout-index-symlinks.sh
+++ b/t/t2005-checkout-index-symlinks.sh
@@ -22,8 +22,10 @@ test_expect_success \
 git checkout-index symlink &&
 test -f symlink'
 
-test_expect_success \
-'the file must be the blob we added during the setup' '
-test "$(git hash-object -t blob symlink)" = $l'
+test_expect_success 'the file must be the blob we added during the setup' '
+	echo "$l" >expect &&
+	git hash-object -t blob symlink >actual &&
+	test_cmp expect actual
+'
 
 test_done
diff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh
index bcff460d0a2..9fb73a8c3eb 100755
--- a/t/t5522-pull-symlink.sh
+++ b/t/t5522-pull-symlink.sh
@@ -78,7 +78,9 @@ test_expect_success SYMLINKS 'pushing from symlinked subdir' '
 		git commit -m push ./file &&
 		git push
 	) &&
-	test push = $(git show HEAD:subdir/file)
+	echo push >expect &&
+	git show HEAD:subdir/file >actual &&
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh
index 1927a862839..c74798e8d24 100755
--- a/t/t7402-submodule-rebase.sh
+++ b/t/t7402-submodule-rebase.sh
@@ -55,12 +55,15 @@ chmod a+x fake-editor.sh
 
 test_expect_success 'interactive rebase with a dirty submodule' '
 
-	test submodule = $(git diff --name-only) &&
+	echo submodule >expect &&
+	git diff --name-only >actual &&
+	test_cmp expect actual &&
 	HEAD=$(git rev-parse HEAD) &&
 	GIT_EDITOR="\"$(pwd)/fake-editor.sh\"" EDITOR_TEXT="pick $HEAD" \
 		git rebase -i HEAD^ &&
-	test submodule = $(git diff --name-only)
-
+	echo submodule >expect &&
+	git diff --name-only >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'rebase with dirty file and submodule fails' '
diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh
index 07ca46fb0d5..d1255228d5f 100755
--- a/t/t7504-commit-msg-hook.sh
+++ b/t/t7504-commit-msg-hook.sh
@@ -102,7 +102,9 @@ test_expect_success 'setup: commit-msg hook that always fails' '
 '
 
 commit_msg_is () {
-	test "$(git log --pretty=format:%s%b -1)" = "$1"
+	printf "%s" "$1" >expect &&
+	git log --pretty=format:%s%b -1 >actual &&
+	test_cmp expect actual
 }
 
 test_expect_success 'with failing hook' '
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 8eded6ab274..39d6d713ecb 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -1001,7 +1001,9 @@ test_expect_success 'log --committer does not search in timestamp' '
 test_expect_success 'grep with CE_VALID file' '
 	git update-index --assume-unchanged t/t &&
 	rm t/t &&
-	test "$(git grep test)" = "t/t:test" &&
+	echo "t/t:test" >expect &&
+	git grep test >actual &&
+	test_cmp expect actual &&
 	git update-index --no-assume-unchanged t/t &&
 	git checkout t/t
 '
-- 
2.39.1.1425.gac85d95d48c


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v5 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )"
  2023-02-06 22:44       ` [PATCH v5 " Ævar Arnfjörð Bjarmason
                           ` (3 preceding siblings ...)
  2023-02-06 22:44         ` [PATCH v5 4/6] tests: don't lose exit status with "test <op> $(git ...)" Ævar Arnfjörð Bjarmason
@ 2023-02-06 22:44         ` Ævar Arnfjörð Bjarmason
  2023-02-06 22:44         ` [PATCH v5 6/6] tests: don't lose misc "git" exit codes Ævar Arnfjörð Bjarmason
  2023-02-06 23:33         ` [PATCH v5 0/6] tests: fix ignored & hidden " Junio C Hamano
  6 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2023-02-06 22:44 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Phillip Wood,
	Ævar Arnfjörð Bjarmason

Change tests that would lose the "git" exit code via a negation
pattern to:

- In the case of "t0055-beyond-symlinks.sh" compare against the
  expected output instead.

  We could use the same pattern as in the "t3700-add.sh" below, doing
  so would have the advantage that if we added an earlier test we
  wouldn't need to adjust the "expect" output.

  But as "t0055-beyond-symlinks.sh" is a small and focused test (less
  than 40 lines in total) let's use "test_cmp" instead.

- For "t3700-add.sh" use "sed -n" to print the expected "bad" part,
  and use "test_must_be_empty" to assert that it's not there. If we used
  "grep" we'd get a non-zero exit code.

  We could use "test_expect_code 1 grep", but this is more consistent
  with existing patterns in the test suite.

  We can also remove a repeated invocation of "git ls-files" for the
  last test that's being modified in that file, and search the
  existing "files" output instead.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0055-beyond-symlinks.sh | 14 ++++++++++++--
 t/t3700-add.sh             | 18 +++++++++++++-----
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/t/t0055-beyond-symlinks.sh b/t/t0055-beyond-symlinks.sh
index 6bada370225..c3eb1158ef9 100755
--- a/t/t0055-beyond-symlinks.sh
+++ b/t/t0055-beyond-symlinks.sh
@@ -15,12 +15,22 @@ test_expect_success SYMLINKS setup '
 
 test_expect_success SYMLINKS 'update-index --add beyond symlinks' '
 	test_must_fail git update-index --add c/d &&
-	! ( git ls-files | grep c/d )
+	cat >expect <<-\EOF &&
+	a
+	b/d
+	EOF
+	git ls-files >actual &&
+	test_cmp expect actual
 '
 
 test_expect_success SYMLINKS 'add beyond symlinks' '
 	test_must_fail git add c/d &&
-	! ( git ls-files | grep c/d )
+	cat >expect <<-\EOF &&
+	a
+	b/d
+	EOF
+	git ls-files >actual &&
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index 51afbd7b24a..82dd768944f 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -106,24 +106,32 @@ test_expect_success '.gitignore test setup' '
 
 test_expect_success '.gitignore is honored' '
 	git add . &&
-	! (git ls-files | grep "\\.ig")
+	git ls-files >files &&
+	sed -n "/\\.ig/p" <files >actual &&
+	test_must_be_empty actual
 '
 
 test_expect_success 'error out when attempting to add ignored ones without -f' '
 	test_must_fail git add a.?? &&
-	! (git ls-files | grep "\\.ig")
+	git ls-files >files &&
+	sed -n "/\\.ig/p" <files >actual &&
+	test_must_be_empty actual
 '
 
 test_expect_success 'error out when attempting to add ignored ones without -f' '
 	test_must_fail git add d.?? &&
-	! (git ls-files | grep "\\.ig")
+	git ls-files >files &&
+	sed -n "/\\.ig/p" <files >actual &&
+	test_must_be_empty actual
 '
 
 test_expect_success 'error out when attempting to add ignored ones but add others' '
 	touch a.if &&
 	test_must_fail git add a.?? &&
-	! (git ls-files | grep "\\.ig") &&
-	(git ls-files | grep a.if)
+	git ls-files >files &&
+	sed -n "/\\.ig/p" <files >actual &&
+	test_must_be_empty actual &&
+	grep a.if files
 '
 
 test_expect_success 'add ignored ones with -f' '
-- 
2.39.1.1425.gac85d95d48c


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [PATCH v5 6/6] tests: don't lose misc "git" exit codes
  2023-02-06 22:44       ` [PATCH v5 " Ævar Arnfjörð Bjarmason
                           ` (4 preceding siblings ...)
  2023-02-06 22:44         ` [PATCH v5 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )" Ævar Arnfjörð Bjarmason
@ 2023-02-06 22:44         ` Ævar Arnfjörð Bjarmason
  2023-02-06 23:33         ` [PATCH v5 0/6] tests: fix ignored & hidden " Junio C Hamano
  6 siblings, 0 replies; 83+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2023-02-06 22:44 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, René Scharfe, Eric Sunshine,
	Torsten Bögershausen, Phillip Wood,
	Ævar Arnfjörð Bjarmason

Fix a few miscellaneous cases where:

- We lost the "git" exit code via "git ... | grep"
- Likewise by having a $(git) argument to git itself
- Used "test -z" to check that a command emitted no output, we can use
  "test_must_be_empty" and &&-chaining instead.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1401-symbolic-ref.sh    | 3 ++-
 t/t3701-add-interactive.sh | 8 +++++---
 t/t7516-commit-races.sh    | 3 ++-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh
index d708acdb819..5e36899d207 100755
--- a/t/t1401-symbolic-ref.sh
+++ b/t/t1401-symbolic-ref.sh
@@ -33,7 +33,8 @@ test_expect_success 'symbolic-ref refuses non-ref for HEAD' '
 reset_to_sane
 
 test_expect_success 'symbolic-ref refuses bare sha1' '
-	test_must_fail git symbolic-ref HEAD $(git rev-parse HEAD)
+	rev=$(git rev-parse HEAD) &&
+	test_must_fail git symbolic-ref HEAD "$rev"
 '
 
 reset_to_sane
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 5841f280fb2..f1fe5d60677 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -296,9 +296,11 @@ test_expect_success FILEMODE 'stage mode and hunk' '
 	echo content >>file &&
 	chmod +x file &&
 	printf "y\\ny\\n" | git add -p &&
-	git diff --cached file | grep "new mode" &&
-	git diff --cached file | grep "+content" &&
-	test -z "$(git diff file)"
+	git diff --cached file >out &&
+	grep "new mode" out &&
+	grep "+content" out &&
+	git diff file >out &&
+	test_must_be_empty out
 '
 
 # end of tests disabled when filemode is not usable
diff --git a/t/t7516-commit-races.sh b/t/t7516-commit-races.sh
index f2ce14e9071..2d38a16480e 100755
--- a/t/t7516-commit-races.sh
+++ b/t/t7516-commit-races.sh
@@ -10,7 +10,8 @@ test_expect_success 'race to create orphan commit' '
 	test_must_fail env EDITOR=./hare-editor git commit --allow-empty -m tortoise -e &&
 	git show -s --pretty=format:%s >subject &&
 	grep hare subject &&
-	test -z "$(git show -s --pretty=format:%P)"
+	git show -s --pretty=format:%P >out &&
+	test_must_be_empty out
 '
 
 test_expect_success 'race to create non-orphan commit' '
-- 
2.39.1.1425.gac85d95d48c


^ permalink raw reply related	[flat|nested] 83+ messages in thread

* Re: [PATCH v5 0/6] tests: fix ignored & hidden exit codes
  2023-02-06 22:44       ` [PATCH v5 " Ævar Arnfjörð Bjarmason
                           ` (5 preceding siblings ...)
  2023-02-06 22:44         ` [PATCH v5 6/6] tests: don't lose misc "git" exit codes Ævar Arnfjörð Bjarmason
@ 2023-02-06 23:33         ` Junio C Hamano
  6 siblings, 0 replies; 83+ messages in thread
From: Junio C Hamano @ 2023-02-06 23:33 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, René Scharfe, Eric Sunshine, Torsten Bögershausen,
	Phillip Wood

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Ævar Arnfjörð Bjarmason (6):
>   auto-crlf tests: don't lose exit code in loops and outside tests
>   t/lib-patch-mode.sh: fix ignored exit codes
>   tests: don't lose exit status with "(cd ...; test <op> $(git ...))"
>   tests: don't lose exit status with "test <op> $(git ...)"
>   tests: don't lose "git" exit codes in "! ( git ... | grep )"
>   tests: don't lose misc "git" exit codes

The changes relative to the previous round look OK.  Will queue.

Thanks.

^ permalink raw reply	[flat|nested] 83+ messages in thread

end of thread, other threads:[~2023-02-06 23:34 UTC | newest]

Thread overview: 83+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-21  6:51 [PATCH 0/6] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
2022-07-21  6:51 ` [PATCH 1/6] diff tests: fix ignored exit codes in t4023 Ævar Arnfjörð Bjarmason
2022-07-21  6:51 ` [PATCH 2/6] t/lib-patch-mode.sh: fix ignored "git" exit codes Ævar Arnfjörð Bjarmason
2022-07-21  6:51 ` [PATCH 3/6] auto-crlf tests: check "git checkout" exit code Ævar Arnfjörð Bjarmason
2022-07-21  6:51 ` [PATCH 4/6] test-lib-functions: add and use test_cmp_cmd Ævar Arnfjörð Bjarmason
2022-07-21  6:51 ` [PATCH 5/6] merge tests: don't ignore "rev-parse" exit code in helper Ævar Arnfjörð Bjarmason
2022-07-21  6:51 ` [PATCH 6/6] log tests: don't use "exit 1" outside a sub-shell Ævar Arnfjörð Bjarmason
2022-12-02  0:06 ` [PATCH v2 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
2022-12-02  0:06   ` [PATCH v2 1/8] log tests: don't use "exit 1" outside a sub-shell Ævar Arnfjörð Bjarmason
2022-12-02  1:02     ` Eric Sunshine
2022-12-02  1:48       ` Junio C Hamano
2022-12-02  2:45         ` Ævar Arnfjörð Bjarmason
2022-12-02  9:03           ` Eric Sunshine
2022-12-02 10:02             ` Ævar Arnfjörð Bjarmason
2022-12-07  6:09               ` Eric Sunshine
2022-12-02  3:24       ` Junio C Hamano
2022-12-02  0:06   ` [PATCH v2 2/8] auto-crlf tests: check "git checkout" exit code Ævar Arnfjörð Bjarmason
2022-12-02  1:02     ` René Scharfe
2022-12-02  1:10       ` Eric Sunshine
2022-12-02  5:59       ` Torsten Bögershausen
2022-12-02  6:03         ` Eric Sunshine
2022-12-02  0:06   ` [PATCH v2 3/8] diff tests: fix ignored exit codes in t4023 Ævar Arnfjörð Bjarmason
2022-12-02  2:02     ` Junio C Hamano
2022-12-02  0:06   ` [PATCH v2 4/8] test-lib-functions: add and use test_cmp_cmd Ævar Arnfjörð Bjarmason
2022-12-02  1:30     ` René Scharfe
2022-12-02  1:33     ` Eric Sunshine
2022-12-02  1:45       ` Eric Sunshine
2022-12-02  1:52         ` Eric Sunshine
2022-12-02  3:41         ` Junio C Hamano
2022-12-02  0:06   ` [PATCH v2 5/8] t/lib-patch-mode.sh: fix ignored "git" exit codes Ævar Arnfjörð Bjarmason
2022-12-02  1:31     ` René Scharfe
2022-12-02  0:06   ` [PATCH v2 6/8] merge tests: don't ignore "rev-parse" exit code in helper Ævar Arnfjörð Bjarmason
2022-12-02  1:41     ` René Scharfe
2022-12-02  0:06   ` [PATCH v2 7/8] tests: use "test_cmp_cmd" instead of "test" in sub-shells Ævar Arnfjörð Bjarmason
2022-12-02  0:06   ` [PATCH v2 8/8] tests: use "test_cmp_cmd" in misc tests Ævar Arnfjörð Bjarmason
2022-12-02  2:19     ` Junio C Hamano
2022-12-02 11:52   ` [PATCH v3 0/8] tests: fix ignored & hidden exit codes Ævar Arnfjörð Bjarmason
2022-12-02 11:52     ` [PATCH v3 1/8] merge tests: don't ignore "rev-parse" exit code in helper Ævar Arnfjörð Bjarmason
2022-12-05  0:24       ` Junio C Hamano
2022-12-02 11:52     ` [PATCH v3 2/8] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
2022-12-02 15:59       ` René Scharfe
2022-12-02 11:52     ` [PATCH v3 3/8] diff tests: fix ignored exit codes in t4023 Ævar Arnfjörð Bjarmason
2022-12-05  0:26       ` Junio C Hamano
2022-12-02 11:52     ` [PATCH v3 4/8] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
2022-12-02 15:59       ` René Scharfe
2022-12-04  0:45       ` Eric Sunshine
2022-12-02 11:52     ` [PATCH v3 5/8] tests: use "test_cmp" instead of "test" in sub-shells Ævar Arnfjörð Bjarmason
2022-12-05  0:39       ` Junio C Hamano
2022-12-02 11:52     ` [PATCH v3 6/8] tests: don't lose 'test <str> = $(cmd ...)"' exit code Ævar Arnfjörð Bjarmason
2022-12-02 11:52     ` [PATCH v3 7/8] tests: don't lose "git" exit codes in "! ( git ... | grep )" Ævar Arnfjörð Bjarmason
2022-12-02 18:31       ` René Scharfe
2022-12-02 11:52     ` [PATCH v3 8/8] tests: don't lose mist "git" exit codes Ævar Arnfjörð Bjarmason
2022-12-04  0:40       ` Eric Sunshine
2022-12-05  0:45         ` Junio C Hamano
2022-12-19 10:19     ` [PATCH v4 0/6] tests: fix ignored & hidden " Ævar Arnfjörð Bjarmason
2022-12-19 10:19       ` [PATCH v4 1/6] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
2022-12-19 12:07         ` René Scharfe
2022-12-19 10:19       ` [PATCH v4 2/6] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
2022-12-20  0:09         ` Junio C Hamano
2022-12-27 16:40         ` Phillip Wood
2022-12-27 18:14           ` Ævar Arnfjörð Bjarmason
2022-12-19 10:19       ` [PATCH v4 3/6] tests: don't lose exit status with "(cd ...; test <op> $(git ...))" Ævar Arnfjörð Bjarmason
2022-12-20  0:20         ` Junio C Hamano
2022-12-19 10:19       ` [PATCH v4 4/6] tests: don't lose exit status with "test <op> $(git ...)" Ævar Arnfjörð Bjarmason
2022-12-26  1:14         ` Junio C Hamano
2022-12-19 10:19       ` [PATCH v4 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )" Ævar Arnfjörð Bjarmason
2022-12-26  1:18         ` Junio C Hamano
2022-12-27 16:44         ` Phillip Wood
2022-12-27 17:13           ` Phillip Wood
2022-12-27 23:16           ` Junio C Hamano
2022-12-19 10:19       ` [PATCH v4 6/6] tests: don't lose misc "git" exit codes Ævar Arnfjörð Bjarmason
2022-12-27 16:46         ` Phillip Wood
2022-12-27 18:18           ` Ævar Arnfjörð Bjarmason
2022-12-27 23:17           ` Junio C Hamano
2022-12-20  0:06       ` [PATCH v4 0/6] tests: fix ignored & hidden " Junio C Hamano
2023-02-06 22:44       ` [PATCH v5 " Ævar Arnfjörð Bjarmason
2023-02-06 22:44         ` [PATCH v5 1/6] auto-crlf tests: don't lose exit code in loops and outside tests Ævar Arnfjörð Bjarmason
2023-02-06 22:44         ` [PATCH v5 2/6] t/lib-patch-mode.sh: fix ignored exit codes Ævar Arnfjörð Bjarmason
2023-02-06 22:44         ` [PATCH v5 3/6] tests: don't lose exit status with "(cd ...; test <op> $(git ...))" Ævar Arnfjörð Bjarmason
2023-02-06 22:44         ` [PATCH v5 4/6] tests: don't lose exit status with "test <op> $(git ...)" Ævar Arnfjörð Bjarmason
2023-02-06 22:44         ` [PATCH v5 5/6] tests: don't lose "git" exit codes in "! ( git ... | grep )" Ævar Arnfjörð Bjarmason
2023-02-06 22:44         ` [PATCH v5 6/6] tests: don't lose misc "git" exit codes Ævar Arnfjörð Bjarmason
2023-02-06 23:33         ` [PATCH v5 0/6] tests: fix ignored & hidden " Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).