The order in which the stdout and stderr streams are flushed is not guaranteed to be the same across platforms or `libc` implementations. This lack of determinism can lead to anomalous and potentially confusing output if normal (stdout) output is flushed after error (stderr) output. For instance, the following output which clearly indicates a failure due to a fatal error: % git worktree add ../foo bar Preparing worktree (checking out 'bar') fatal: 'bar' is already checked out at '.../wherever' has been reported[1] on Microsoft Windows to appear as: % git worktree add ../foo bar fatal: 'bar' is already checked out at '.../wherever' Preparing worktree (checking out 'bar') which may confuse the reader into thinking that the command somehow recovered and ran to completion despite the error. Rather than attempting to address this issue on a case by case basis, address it by making vreportf() -- which is the heart of error-reporting functions die(), error(), warn(), etc. -- flush stdout before emitting the error message to stderr. [1]: https://lore.kernel.org/git/CA+34VNLj6VB1kCkA=MfM7TZR+6HgqNi5-UaziAoCXacSVkch4A@xxxxxxxxxxxxxx/T/ Signed-off-by: Eric Sunshine <sunshine@xxxxxxxxxxxxxx> --- This is RFC because I naturally worry about potential fallout from making a change to such a core function. I can't think of any case that it wouldn't be advantageous to flush stdout before stderr, so this change _seems_ safe, however, it may be that I'm just not imaginative enough, hence my hesitancy. usage.c | 1 + 1 file changed, 1 insertion(+) diff --git a/usage.c b/usage.c index c7d233b0de..0fc7640b25 100644 --- a/usage.c +++ b/usage.c @@ -27,6 +27,7 @@ void vreportf(const char *prefix, const char *err, va_list params) } *(p++) = '\n'; /* we no longer need a NUL */ + fflush(stdout); fflush(stderr); write_in_full(2, msg, p - msg); } -- 2.34.1.75.gabe6bb3905