{"thread":{"id":"64248","subject":"Git Status Short Output Color Inconsistency with -z Flag","startedAt":"2025-10-05T00:48:57Z","lastAt":"2025-10-18T15:09:11Z","messageCount":7,"participants":["Langbart","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"527922","messageId":"XCDlwEkTlgoZIyIf_8BfOGl1C3C63Ioxeib4BRNJ9Jm_CtYWKT3qu-pDaeXVtS1Ifq6E4pT9G0yDbIS_nSwN-uiBuBNAlMyrOv0R1RyM7oc=@protonmail.com","threadId":"64248","inReplyTo":null,"subject":"Git Status Short Output Color Inconsistency with -z Flag","fromName":"Langbart","fromEmail":"langbart@protonmail.com","sentAt":"2025-10-05T00:48:43Z","receivedAt":"2025-10-05T00:48:57Z","isPatch":false,"sender":{"key":"langbart@protonmail.com","avatar":null},"body":"What did you do before the bug happened? (Steps to reproduce your issue)\n\n1. Create an untracked file and modify an existing tracked file\n2. Run: git status --short -z\n\nWhat did you expect to happen? (Expected behavior)\n\nAll status markers have colors disabled\n\nWhat happened instead? (Actual behavior)\n\n- Modified marker (`M`) appears colored\n- Untracked marker (`??`) appears *uncolored*\n\n\nRelated patch:\n\nhttps://lore.kernel.org/git/cover.1260025135.git.git@drmicha.warpmail.net/T/#u\n\ngit version 2.51.0\n"},{"id":"528053","messageId":"20251007082920.GA3349249@coredump.intra.peff.net","threadId":"64248","inReplyTo":"XCDlwEkTlgoZIyIf_8BfOGl1C3C63Ioxeib4BRNJ9Jm_CtYWKT3qu-pDaeXVtS1Ifq6E4pT9G0yDbIS_nSwN-uiBuBNAlMyrOv0R1RyM7oc=@protonmail.com","subject":"Re: Git Status Short Output Color Inconsistency with -z Flag","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2025-10-07T08:29:20Z","receivedAt":"2025-10-07T08:29:21Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Oct 05, 2025 at 12:48:43AM +0000, Langbart wrote:\n\n> What did you do before the bug happened? (Steps to reproduce your issue)\n> \n> 1. Create an untracked file and modify an existing tracked file\n> 2. Run: git status --short -z\n> \n> What did you expect to happen? (Expected behavior)\n> \n> All status markers have colors disabled\n> \n> What happened instead? (Actual behavior)\n> \n> - Modified marker (`M`) appears colored\n> - Untracked marker (`??`) appears *uncolored*\n\nThere is a bug here, but I don't think your expectation matches the\ndocumentation. In the --short output, we do still respect color. We do\nnot for the machine-readable --porcelain output, which is also implied\nby \"-z\" without another format.\n\nSo either of:\n\n  git status -z --porcelain\n\n  # this implies --porcelain=v1\n  git status -z\n\nwill do what you expected. Asking for \"-z --short\" is a bit unusual,\nsince \"--short\" is meant to be human-readable and \"-z\" generally is not.\nSo I'd expect it to be used only for relaying colorized information to a\nhuman over another channel or something.\n\nBut back to the bug. As you noticed, one item is colorized and the other\nis not. I think the fix is probably this:\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 8ffe6d3988..e12adb26b9 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -2042,13 +2042,13 @@ static void wt_shortstatus_status(struct string_list_item *it,\n static void wt_shortstatus_other(struct string_list_item *it,\n \t\t\t\t struct wt_status *s, const char *sign)\n {\n+\tcolor_fprintf(s->fp, color(WT_STATUS_UNTRACKED, s), \"%s\", sign);\n \tif (s->null_termination) {\n-\t\tfprintf(s->fp, \"%s %s%c\", sign, it->string, 0);\n+\t\tfprintf(s->fp, \" %s%c\", it->string, 0);\n \t} else {\n \t\tstruct strbuf onebuf = STRBUF_INIT;\n \t\tconst char *one;\n \t\tone = quote_path(it->string, s->prefix, &onebuf, QUOTE_PATH_QUOTE_SP);\n-\t\tcolor_fprintf(s->fp, color(WT_STATUS_UNTRACKED, s), \"%s\", sign);\n \t\tfprintf(s->fp, \" %s\\n\", one);\n \t\tstrbuf_release(&onebuf);\n \t}\n\nwhich matches how other output functions like wt_shortstatus_unmerged()\nbehave (handling color before hitting the null_termination conditional).\n\n-Peff\n"},{"id":"528161","messageId":"20251007203406.GA4028057@coredump.intra.peff.net","threadId":"64248","inReplyTo":"20251007082920.GA3349249@coredump.intra.peff.net","subject":"[PATCH] status: make coloring of \"-z --short\" consistent","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2025-10-07T20:34:06Z","receivedAt":"2025-10-07T20:34:11Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"When running \"git status -z --short\", the marker on modified index\nentries (e.g., \"M\") is colorized, but the \"??\" marker for untracked\nentries is not. Let's fix the \"??\" entries to show color here.\n\nAt first glance you might think that neither should be colorized, as\nusually one would use \"-z\" to get machine-readable output. But this is a\ntricky and unusual case. We have two output formats, \"--short\" and\n\"--porcelain\", which are substantially similar but differ in that\n\"--short\" is for humans and \"--porcelain\" is for machines. And \"-z\" by\nitself, without any other output option, does default to \"--porcelain\",\nso \"git status -z\" is for machines and will not colorize anything.\n\nBut if you ask for \"-z\" and \"--short\" together, then that is explicitly\nasking for the human-readable output, but separated by NULs. This is\nunlikely to be useful directly, but could for example be used if the\noutput will be shown to a human outside of the terminal. At any rate,\nthe current behavior is clearly wrong (since we colorize some things but\nnot others), and I think colorizing everything is the least-surprising\nthing we can do here.\n\nReported-by: Langbart <Langbart@protonmail.com>\nSigned-off-by: Jeff King <peff@peff.net>\n---\nSame fix that I posted earlier, but now with a test and a commit\nmessage.\n\n t/t7508-status.sh | 11 +++++++++++\n wt-status.c       |  4 ++--\n 2 files changed, 13 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t7508-status.sh b/t/t7508-status.sh\nindex cdc1d6fcc7..abad229e9d 100755\n--- a/t/t7508-status.sh\n+++ b/t/t7508-status.sh\n@@ -717,6 +717,17 @@ test_expect_success TTY 'status -s with color.status' '\n \n '\n \n+test_expect_success TTY 'status -s keeps colors with -z' '\n+\ttest_when_finished \"rm -f output.*\" &&\n+\ttest_terminal git status -s -z >output.raw &&\n+\t# convert back to newlines to avoid portability issues with\n+\t# test_decode_color and test_cmp, and to let us use the same expected\n+\t# output as earlier tests\n+\ttr \"\\0\" \"\\n\" <output.raw >output.nl &&\n+\ttest_decode_color <output.nl >output &&\n+\ttest_cmp expect output\n+'\n+\n cat >expect <<\\EOF\n ## <YELLOW>main<RESET>...<CYAN>upstream<RESET> [ahead <YELLOW>1<RESET>, behind <CYAN>2<RESET>]\n  <RED>M<RESET> dir1/modified\ndiff --git a/wt-status.c b/wt-status.c\nindex 8ffe6d3988..e12adb26b9 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -2042,13 +2042,13 @@ static void wt_shortstatus_status(struct string_list_item *it,\n static void wt_shortstatus_other(struct string_list_item *it,\n \t\t\t\t struct wt_status *s, const char *sign)\n {\n+\tcolor_fprintf(s->fp, color(WT_STATUS_UNTRACKED, s), \"%s\", sign);\n \tif (s->null_termination) {\n-\t\tfprintf(s->fp, \"%s %s%c\", sign, it->string, 0);\n+\t\tfprintf(s->fp, \" %s%c\", it->string, 0);\n \t} else {\n \t\tstruct strbuf onebuf = STRBUF_INIT;\n \t\tconst char *one;\n \t\tone = quote_path(it->string, s->prefix, &onebuf, QUOTE_PATH_QUOTE_SP);\n-\t\tcolor_fprintf(s->fp, color(WT_STATUS_UNTRACKED, s), \"%s\", sign);\n \t\tfprintf(s->fp, \" %s\\n\", one);\n \t\tstrbuf_release(&onebuf);\n \t}\n-- \n2.51.0.717.g1fc658c4b9\n\n"},{"id":"529049","messageId":"20251017084455.GA4096702@coredump.intra.peff.net","threadId":"64248","inReplyTo":"20251007203406.GA4028057@coredump.intra.peff.net","subject":"[PATCH resend] status: make coloring of \"-z --short\" consistent","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2025-10-17T08:44:55Z","receivedAt":"2025-10-17T08:44:56Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"When running \"git status -z --short\", the marker on modified index\nentries (e.g., \"M\") is colorized, but the \"??\" marker for untracked\nentries is not. Let's fix the \"??\" entries to show color here.\n\nAt first glance you might think that neither should be colorized, as\nusually one would use \"-z\" to get machine-readable output. But this is a\ntricky and unusual case. We have two output formats, \"--short\" and\n\"--porcelain\" which are substantially similar, but differ in that\n\"--short\" is for humans who want something short and \"--porcelain\" is\nfor machines. And \"-z\" by itself, without any other output option, does\ndefault to \"--porcelain\", so \"git status -z\" will not colorize anything.\n\nBut if you explicitly ask for \"-z\" and \"--short\" together, then that is\nasking for the human-readable output, but separated by NULs. This is\nunlikely to be useful directly, but could for example be used if the\noutput will be shown to a human outside of the terminal. At any rate,\nthe current behavior is clearly wrong (since we colorize some things but\nnot others), and I think colorizing everything is the least-surprising\nthing we can do here.\n\nReported-by: Langbart <Langbart@protonmail.com>\nSigned-off-by: Jeff King <peff@peff.net>\n---\nRe-sending unmodified, as the original from 10 days ago did not generate\nany discussion, and doesn't seem to have been picked up for 'seen'.\n\n t/t7508-status.sh | 11 +++++++++++\n wt-status.c       |  4 ++--\n 2 files changed, 13 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t7508-status.sh b/t/t7508-status.sh\nindex cdc1d6fcc7..abad229e9d 100755\n--- a/t/t7508-status.sh\n+++ b/t/t7508-status.sh\n@@ -717,6 +717,17 @@ test_expect_success TTY 'status -s with color.status' '\n \n '\n \n+test_expect_success TTY 'status -s keeps colors with -z' '\n+\ttest_when_finished \"rm -f output.*\" &&\n+\ttest_terminal git status -s -z >output.raw &&\n+\t# convert back to newlines to avoid portability issues with\n+\t# test_decode_color and test_cmp, and to let us use the same expected\n+\t# output as earlier tests\n+\ttr \"\\0\" \"\\n\" <output.raw >output.nl &&\n+\ttest_decode_color <output.nl >output &&\n+\ttest_cmp expect output\n+'\n+\n cat >expect <<\\EOF\n ## <YELLOW>main<RESET>...<CYAN>upstream<RESET> [ahead <YELLOW>1<RESET>, behind <CYAN>2<RESET>]\n  <RED>M<RESET> dir1/modified\ndiff --git a/wt-status.c b/wt-status.c\nindex 8ffe6d3988..e12adb26b9 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -2042,13 +2042,13 @@ static void wt_shortstatus_status(struct string_list_item *it,\n static void wt_shortstatus_other(struct string_list_item *it,\n \t\t\t\t struct wt_status *s, const char *sign)\n {\n+\tcolor_fprintf(s->fp, color(WT_STATUS_UNTRACKED, s), \"%s\", sign);\n \tif (s->null_termination) {\n-\t\tfprintf(s->fp, \"%s %s%c\", sign, it->string, 0);\n+\t\tfprintf(s->fp, \" %s%c\", it->string, 0);\n \t} else {\n \t\tstruct strbuf onebuf = STRBUF_INIT;\n \t\tconst char *one;\n \t\tone = quote_path(it->string, s->prefix, &onebuf, QUOTE_PATH_QUOTE_SP);\n-\t\tcolor_fprintf(s->fp, color(WT_STATUS_UNTRACKED, s), \"%s\", sign);\n \t\tfprintf(s->fp, \" %s\\n\", one);\n \t\tstrbuf_release(&onebuf);\n \t}\n-- \n2.51.1.685.g6bf3278fbc\n\n"},{"id":"529114","messageId":"5y1mZIuIa13McbaoEhdBCm8CNMyjkJ6UE39s0kB-rYSmAmuPFnAof5fNVatncDUXIRoMvlpdbId3nFn2dnwU8NwNk78XArUYCf3RncWHu6c=@protonmail.com","threadId":"64248","inReplyTo":"20251017084455.GA4096702@coredump.intra.peff.net","subject":"Re: [PATCH resend] status: make coloring of \"-z --short\" consistent","fromName":"Langbart","fromEmail":"langbart@protonmail.com","sentAt":"2025-10-18T06:01:07Z","receivedAt":"2025-10-18T06:01:18Z","isPatch":true,"sender":{"key":"langbart@protonmail.com","avatar":null},"body":"Thanks for the patch. Agreed, Retaining the colors is very useful, \nallowing me to pipe the colored output to other tools.\n\ngit -c color.status=always status --short -z | fzf --read0\n"},{"id":"529119","messageId":"20251018095026.GD1060824@coredump.intra.peff.net","threadId":"64248","inReplyTo":"5y1mZIuIa13McbaoEhdBCm8CNMyjkJ6UE39s0kB-rYSmAmuPFnAof5fNVatncDUXIRoMvlpdbId3nFn2dnwU8NwNk78XArUYCf3RncWHu6c=@protonmail.com","subject":"Re: [PATCH resend] status: make coloring of \"-z --short\" consistent","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2025-10-18T09:50:26Z","receivedAt":"2025-10-18T09:50:28Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Oct 18, 2025 at 06:01:07AM +0000, Langbart wrote:\n\n> Thanks for the patch. Agreed, Retaining the colors is very useful, \n> allowing me to pipe the colored output to other tools.\n> \n> git -c color.status=always status --short -z | fzf --read0\n\nThanks, my intuition is that something like that could be useful, but I\ndidn't have a concrete example. That one is perfect.\n\n(If anybody tries the above, note that I needed to add \"--ansi\" for it\nto look nice in fzf. But I don't usually use that program, so I imagine\nthere's a way to configure it to do that by default).\n\n-Peff\n"},{"id":"529127","messageId":"m-o4xSH-_z7mD-3ehDnJCp-J3JOsEeo65xRb3BxywaB3voOguES48T4E-mjZwdmqwcP-TxF6kcr6nKMU6YE2z8SkncQl5jXDqdFH6xcl6S0=@protonmail.com","threadId":"64248","inReplyTo":"20251018095026.GD1060824@coredump.intra.peff.net","subject":"Re: [PATCH resend] status: make coloring of \"-z --short\" consistent","fromName":"Langbart","fromEmail":"langbart@protonmail.com","sentAt":"2025-10-18T15:08:56Z","receivedAt":"2025-10-18T15:09:11Z","isPatch":true,"sender":{"key":"langbart@protonmail.com","avatar":null},"body":"\n> Thanks, my intuition is that something like that could be useful, but I\n> didn't have a concrete example. That one is perfect.\n\nGreat, I'll pass it to the fzf maintainer, who proposed it.\n\n> (If anybody tries the above, note that I needed to add \"--ansi\" for it\n> to look nice in fzf. But I don't usually use that program, so I imagine\n> there's a way to configure it to do that by default).\n\nYou're right. I only set it in my environment variable:\n\nexport FZF_DEFAULT_OPTS=\"--ansi\"\n\nThanks for the fix and for being active here. I've come across your name a few\ntimes while searching the git.vger.kernel.org archive mirror for issues, and\nI've always appreciated your thoughtful replies.\n"}]}