mingw: optionally redirect stderr/stdout via the same handle

The "2>&1" notation in Powershell and in Unix shells implies that stderr is redirected to the same handle into which stdout is already written. Let's use this special value to allow the same trick with GIT_REDIRECT_STDERR and GIT_REDIRECT_STDOUT: if the former's value is `2>&1`, then stderr will simply be written to the same handle as stdout. The functionality was suggested by Jeff Hostetler. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Nov 1, 2017 at 18:10 UTC 1a172e4ac1719a068c76384bd077ee65d915ebea
2 files changed +22 -1
compat/mingw.c
+15
@@ -2160,6 +2160,21 @@ static void maybe_redirect_std_handle(const wchar_t *key, DWORD std_id, int fd,
2160 CloseHandle(handle);
2161 return;
2162 }
2163 + if (std_id == STD_ERROR_HANDLE && !wcscmp(buf, L"2>&1")) {
2164 + handle = GetStdHandle(STD_OUTPUT_HANDLE);
2165 + if (handle == INVALID_HANDLE_VALUE) {
2166 + close(fd);
2167 + handle = GetStdHandle(std_id);
2168 + if (handle != INVALID_HANDLE_VALUE)
2169 + CloseHandle(handle);
2170 + } else {
2171 + int new_fd = _open_osfhandle((intptr_t)handle, O_BINARY);
2172 + SetStdHandle(std_id, handle);
2173 + dup2(new_fd, fd);
2174 + /* do *not* close the new_fd: that would close stdout */
2175 + }
2176 + return;
2177 + }
2178 handle = CreateFileW(buf, desired_access, 0, NULL, create_flag,
2179 flags, NULL);
2180 if (handle != INVALID_HANDLE_VALUE) {
t/t0001-init.sh
+7 -1
@@ -456,7 +456,13 @@ test_expect_success 're-init from a linked worktree' '
456 test_expect_success MINGW 'redirect std handles' '
457 GIT_REDIRECT_STDOUT=output.txt git rev-parse --git-dir &&
458 test .git = "$(cat output.txt)" &&
459 - test -z "$(GIT_REDIRECT_STDOUT=off git rev-parse --git-dir)"
459 + test -z "$(GIT_REDIRECT_STDOUT=off git rev-parse --git-dir)" &&
460 + test_must_fail env \
461 + GIT_REDIRECT_STDOUT=output.txt \
462 + GIT_REDIRECT_STDERR="2>&1" \
463 + git rev-parse --git-dir --verify refs/invalid &&
464 + printf ".git\nfatal: Needed a single revision\n" >expect &&
465 + test_cmp expect output.txt
466 '
467
468 test_done