Subject: Re: Bug report: Incorrect GIT_FLUSH behavior in 2.43.1 (regression and breaking)

From: Junio C Hamano <[email-masked]>
Date: Tue, 13 Feb 2024 09:26:47 -0800

Phillip Wood <[email-masked]> writes:

> Given we're in a rc-period a minimal fix like this looks appropriate
> (though it is missing some braces according to our coding
> guidelines). The interaction of "skip_stdout_flush" and git_env_bool()
> is unfortunate, It might be clearer if we changed to having
> "force_stdout_flush" instead but that would be a more invasive change.

I admit that I did find the polarity of the existing variable
annoying, and it does make sense to flip it like you did here.

Unfortunately the minimum fix is already in 'next', so let me turn
what you wrote into an update relative to that.  I'll assume your
patch in the discussion is signed-off already?

------- >8 ------------- >8 ------------- >8 -------
From: Phillip Wood <[email-masked]>
Subject: maybe_flush_or_die(): flip the polarity of an internal variable

We take GIT_FLUSH that tells us if we want to flush (or not) from
the outside, but internally use a variable that tells us to skip (or
not) the flushing operation, which makes the code flow unnecessarily
confusing to read.

With the understanding of the original motivation behind "skip" in
06f59e9f (Don't fflush(stdout) when it's not helpful, 2007-06-29),
we can sympathize with the current naming (we wanted to avoid
useless flushing of stdout by default, with an escape hatch to
always flush), but it is still not a good excuse.

Retire the "skip_stdout_flush" variable and replace it with "flush_stdout"
that tells if we do or do not want to run fflush().

Signed-off-by: Junio C Hamano <[email-masked]>
---
 write-or-die.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git c/write-or-die.c w/write-or-die.c
index 3ecb9e2af5..01a9a51fa2 100644
--- c/write-or-die.c
+++ w/write-or-die.c
@@ -18,23 +18,20 @@
  */
 void maybe_flush_or_die(FILE *f, const char *desc)
 {
-	static int skip_stdout_flush = -1;
-
 	if (f == stdout) {
-		if (skip_stdout_flush < 0) {
-			int flush_setting = git_env_bool("GIT_FLUSH", -1);
+		static int force_flush_stdout = -1;
 
-			if (0 <= flush_setting)
-				skip_stdout_flush = !flush_setting;
-			else {
+		if (force_flush_stdout < 0) {
+			force_flush_stdout = git_env_bool("GIT_FLUSH", -1);
+			if (force_flush_stdout < 0) {
 				struct stat st;
 				if (fstat(fileno(stdout), &st))
-					skip_stdout_flush = 0;
+					force_flush_stdout = 1;
 				else
-					skip_stdout_flush = S_ISREG(st.st_mode);
+					force_flush_stdout = !S_ISREG(st.st_mode);
 			}
 		}
-		if (skip_stdout_flush && !ferror(f))
+		if (!force_flush_stdout && !ferror(f))
 			return;
 	}
 	if (fflush(f)) {