t/test-lib: don't print shell traces to stdout

We have several flags like "--verbose", "--verbose-only" or "-x" that cause us to generate shell traces. The generated tracing output is split up in these cases so that the test's stdout is printed to file descriptor 3 whereas its stderr is printed to file descriptor 4. Depending on which options have been given, we then end up either: - Redirecting both file descriptors to a file. - Redirecting them to stdout and stderr, respectively. - Closing them in case we're running in none-verbose mode. The second case causes problems though when passing output to a TAP parser. We print the test's stdout to the console's stdout, and that results in broken TAP output. Fix the issue by instead redirecting the test's stdout to the shell's stderr. This makes it impossible to discern stdout from stderr, but going by my own experience I never came across a usecase where I would have needed this distinction. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jun 2, 2025 at 08:44 UTC d411d3d837ece4f29b2a23df0bf537795e2dee56
2 files changed +21 -18
t/t0000-basic.sh
+19 -16
@@ -219,41 +219,44 @@ test_expect_success 'subtest: --verbose option' '
219 test_expect_success "failing test" false
220 test_done
221 EOF
222 - mv t1234-verbose/out t1234-verbose/out+ &&
223 - grep -v "^Initialized empty" t1234-verbose/out+ >t1234-verbose/out &&
224 - check_sub_test_lib_test t1234-verbose <<-\EOF
225 - > expecting success of 1234.1 '\''passing test'\'': true
222 + mv t1234-verbose/err t1234-verbose/err+ &&
223 + grep -v "^Initialized empty" t1234-verbose/err+ >t1234-verbose/err &&
224 + check_sub_test_lib_test_err t1234-verbose \
225 + <<-\EOF_OUT 3<<-\EOF_ERR
226 > ok 1 - passing test
227 + > ok 2 - test with output
228 + > not ok 3 - failing test
229 + > # false
230 + > # failed 1 among 3 test(s)
231 + > 1..3
232 + EOF_OUT
233 + > expecting success of 1234.1 '\''passing test'\'': true
234 > Z
235 > expecting success of 1234.2 '\''test with output'\'': echo foo
236 > foo
230 - > ok 2 - test with output
237 > Z
238 > expecting success of 1234.3 '\''failing test'\'': false
233 - > not ok 3 - failing test
234 - > # false
239 > Z
236 - > # failed 1 among 3 test(s)
237 - > 1..3
238 - EOF
240 + EOF_ERR
241 '
242
243 test_expect_success 'subtest: --verbose-only option' '
244 run_sub_test_lib_test_err \
245 t1234-verbose \
246 --verbose-only=2 &&
245 - check_sub_test_lib_test t1234-verbose <<-\EOF
247 + check_sub_test_lib_test_err t1234-verbose <<-\EOF_OUT 3<<-\EOF_ERR
248 > ok 1 - passing test
247 - > Z
248 - > expecting success of 1234.2 '\''test with output'\'': echo foo
249 - > foo
249 > ok 2 - test with output
251 - > Z
250 > not ok 3 - failing test
251 > # false
252 > # failed 1 among 3 test(s)
253 > 1..3
256 - EOF
254 + EOF_OUT
255 + > Z
256 + > expecting success of 1234.2 '\''test with output'\'': echo foo
257 + > foo
258 + > Z
259 + EOF_ERR
260 '
261
262 test_expect_success 'subtest: skip one with GIT_SKIP_TESTS' '
t/test-lib.sh
+2 -2
@@ -707,7 +707,7 @@ then
707 exec 3>>"$GIT_TEST_TEE_OUTPUT_FILE" 4>&3
708 elif test "$verbose" = "t"
709 then
710 - exec 4>&2 3>&1
710 + exec 4>&2 3>&2
711 else
712 exec 4>/dev/null 3>/dev/null
713 fi
@@ -949,7 +949,7 @@ maybe_setup_verbose () {
949 test -z "$verbose_only" && return
950 if match_pattern_list $test_count "$verbose_only"
951 then
952 - exec 4>&2 3>&1
952 + exec 4>&2 3>&2
953 # Emit a delimiting blank line when going from
954 # non-verbose to verbose. Within verbose mode the
955 # delimiter is printed by test_expect_*. The choice