{"thread":{"id":"65590","subject":"Git trims the last character of content from remotes","startedAt":"2026-05-04T17:02:22Z","lastAt":"2026-08-03T15:51:04Z","messageCount":10,"participants":["Hugo Osvaldo Barrera","Chris Torek","Mikael Magnusson","René Scharfe","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"542681","messageId":"2d3f5504-f5dd-4171-96e8-b5633b6a1f5e@app.fastmail.com","threadId":"65590","inReplyTo":null,"subject":"Git trims the last character of content from remotes","fromName":"Hugo Osvaldo Barrera","fromEmail":"hugo@whynothugo.nl","sentAt":"2026-05-04T17:01:50Z","receivedAt":"2026-05-04T17:02:22Z","isPatch":false,"body":"Hi all,\n\nWhen I push content to GitLab, the remote server sends back some text which git\nthen prints to stderr:\n\n  remote:\n  remote: To create a merge request for zk, visit:\n  remote:   https://gitlab.alpinelinux.org/WhyNotHugo/aports/-/merge_requests/new?merge_request%5Bsource_branch%5D=zk\n  remote:\n\nWhen the width of a whole line is the same as my terminal width, the last digit\ngets trimmed off. E.g.: if I resize my terminal for the above to fix exactly,\nand re-run the same command, git prints:\n\n  remote:   https://gitlab.alpinelinux.org/WhyNotHugo/aports/-/merge_requests/new?merge_request%5Bsource_branch%5D=z\n\nFrom what I can tell, sideband.c prints ANSI_SUFFIX = \"\\033[K\", this escape\nsequence being \"clear the line from the current position until the end of the\nline\", and this is the root cause of the issue.\n\nWhen piping to cat or to a file, this sequence is not printed, so the output is\nfine.\n\nIs this a bug?\n\nThanks,\n\nPS: please CC me, as I am not subscribed to the list.\n\n-- \nHugo\n"},{"id":"542735","messageId":"CAPx1Gvf5Vts3oS2BdFQ4PpCR-UY=5cYW7fgOkRuQpi8ug2JXDg@mail.gmail.com","threadId":"65590","inReplyTo":"2d3f5504-f5dd-4171-96e8-b5633b6a1f5e@app.fastmail.com","subject":"Re: Git trims the last character of content from remotes","fromName":"Chris Torek","fromEmail":"chris.torek@gmail.com","sentAt":"2026-05-05T00:34:18Z","receivedAt":"2026-05-05T00:34:32Z","isPatch":false,"body":"On Mon, May 4, 2026 at 10:02 AM Hugo Osvaldo Barrera <hugo@whynothugo.nl> wrote:\n[snippage]\n> When the width of a whole line is the same as my terminal width ...\n[snippage]\n> ... sideband.c prints ANSI_SUFFIX = \"\\033[K\", this escape\n> sequence being \"clear the line from the current position until the end of the\n> line\", and this is the root cause of the issue.\n\nInteresting.\n\nIn Ye Olden Dayes of (n)curses, there was (and still is) a terminal\ncapacity boolean flag, \"xn\" or (in terminfo which is more verbose)\n\"xenl\", the \"terminal eats newline glitch\".\n\nConsider your bog-standard 80x24 \"glass tty\" from the late 1970s /\nearly 1980s. Printing a line of exactly 80 characters caused the\ncursor to march from column 1, to 2, to 3, ..., to 80, to ... column\n81? There is no column 81. So what is this \"glass tty\" to do?\n\nSome acted like a print head, leaving the cursor stuck in column 80,\nso that printing *more* characters just made that big black blob of\nink on the paper er I mean erased each previous character with the new\none printed on top. So then a final \"new line\" sequence left the\ncursor on column 1 of the next line, which is where we want it.\n\nSome thought this was annoying and/or stupid so they immediately\nwrapped to column 1 of the next line, as if the computer had sent a\nnewline sequence. But if the line was in fact exactly 80 characters,\nthis meant the subsequent newline sequence moved to column 1 of the\n*next* row, leaving a blank line (or scrolling the screen twice or\nwhatever). This is Obviously Bad Behavior, but the \"overprint\" answer\nis equally Obviously Bad.\n\nThere were two ways of dealing with the problem intelligently: put the\ncursor to an internal \"column 81\" that, if there's a newline, sends\nthe cursor to column 1 of the next row; or simply set a flag and eat\nthe next character if it's a newline. (This is a little trickier than\nit sounds since the newline sequence is actually CR+LF, or LF+CR,\ndepending on certain computer-maker choices, but it works either way.)\n\nThe xn / xenl flag describes terminals that behave this way. The\nscreen-oriented programs (ex/vi, now vim and emacs and nano and so on,\nplus things like \"more\"/\"less\"/other pagers, etc) would know to send\nan extra newline here if the xn/xenl flag is true, and not if not\nsince the cursor was already on column 1 of the next line\nautomatically. (Though actually this depends on another boolean, \"am\",\nauto-right-margin. Lacking \"am\", the cursor simply hammers on the\nfinal column, the overprint Bad Behavior Mode.)\n\nAlas, this does not describe what happens if one sends the \"clear to\nend of line\" sequence. If the cursor is in the phantom \"column 81\",\nperhaps that sequence does nothing. If it's lingering in column 80,\nperhaps that clears the character under the cursor. All that xn tells\nyou is \"send a newline anyway\".\n\nAs for what to do, well, that could be tricky. Git *could* check for\n\"am\" and \"xn\" / \"xenl\", but that requires parsing termcap/terminfo,\nwhich is kind of a nightmare. It also requires counting cursor column\nmovements, which is something of a mug's game.[1] If you're willing to\nplay that game though, you could just count and, if at the last column\nas determined by \"tty column width\" inquiry, omit the ESC [ K\nentirely: there's nothing to clear. If you have a non-empty prefix\nstring before this \"clear to end of line\" suffix, the solution is more\nobvious: print the ESC [ K as a *prefix* rather than a suffix, but\nthat fails with the empty prefix.\n\nOne last easy possibility is to print an extra space before the ESC [\nK. It's imperfect, as it causes a blank line for these exact-width\nlines, but avoids data loss.\n\nChris\n\n[1]: https://www.merriam-webster.com/dictionary/mug%27s%20game\n"},{"id":"542755","messageId":"CAHYJk3Qvx2i-K7ozLmwyA_S1tbRhf9i2EZa-5sfzBwC5aebeQg@mail.gmail.com","threadId":"65590","inReplyTo":"2d3f5504-f5dd-4171-96e8-b5633b6a1f5e@app.fastmail.com","subject":"Re: Git trims the last character of content from remotes","fromName":"Mikael Magnusson","fromEmail":"mikachu@gmail.com","sentAt":"2026-05-05T09:38:01Z","receivedAt":"2026-05-05T09:38:15Z","isPatch":false,"body":"On Mon, May 4, 2026 at 7:02 PM Hugo Osvaldo Barrera <hugo@whynothugo.nl> wrote:\n>\n> Hi all,\n>\n> When I push content to GitLab, the remote server sends back some text which git\n> then prints to stderr:\n>\n>   remote:\n>   remote: To create a merge request for zk, visit:\n>   remote:   https://gitlab.alpinelinux.org/WhyNotHugo/aports/-/merge_requests/new?merge_request%5Bsource_branch%5D=zk\n>   remote:\n>\n> When the width of a whole line is the same as my terminal width, the last digit\n> gets trimmed off. E.g.: if I resize my terminal for the above to fix exactly,\n> and re-run the same command, git prints:\n>\n>   remote:   https://gitlab.alpinelinux.org/WhyNotHugo/aports/-/merge_requests/new?merge_request%5Bsource_branch%5D=z\n>\n> From what I can tell, sideband.c prints ANSI_SUFFIX = \"\\033[K\", this escape\n> sequence being \"clear the line from the current position until the end of the\n> line\", and this is the root cause of the issue.\n>\n> When piping to cat or to a file, this sequence is not printed, so the output is\n> fine.\n>\n> Is this a bug?\n\ngrep has the same bug with --color, if you have a line of text the\nsame width as your terminal, for the same reason. urxvt supports an\nextension of \\e[3K to clear to end but not erase the character under\nthe cursor if it's wrapped (but not yet moved to the next line). xterm\nhasn't picked it up though, so it's not a general solution,\nunfortunately. It's a little unclear to me why git prints this\nsequence here at all, are we expecting that there is already other\ntext printed on the line? Or is it to clear cells that may have had\nanother background color when the current line was scrolled in? Maybe\nthat case is more unusual and less harmful than actually eating the\nfinal character, that it's not worth clearing?\n\n-- \nMikael Magnusson\n"},{"id":"542781","messageId":"3364c573-b7f4-4ec0-b471-312aa11028fe@web.de","threadId":"65590","inReplyTo":"CAPx1Gvf5Vts3oS2BdFQ4PpCR-UY=5cYW7fgOkRuQpi8ug2JXDg@mail.gmail.com","subject":"Re: Git trims the last character of content from remotes","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-05-05T19:41:00Z","receivedAt":"2026-05-05T19:46:19Z","isPatch":false,"body":"On 5/5/26 2:34 AM, Chris Torek wrote:\n> On Mon, May 4, 2026 at 10:02 AM Hugo Osvaldo Barrera <hugo@whynothugo.nl> wrote:\n> [snippage]\n>> When the width of a whole line is the same as my terminal width ...\n> [snippage]\n>> ... sideband.c prints ANSI_SUFFIX = \"\\033[K\", this escape\n>> sequence being \"clear the line from the current position until the end of the\n>> line\", and this is the root cause of the issue.\n \n> If you have a non-empty prefix\n> string before this \"clear to end of line\" suffix, the solution is more\n> obvious: print the ESC [ K as a *prefix* rather than a suffix, but\n> that fails with the empty prefix.\nWe do have a non-empty prefix, but why would it be necessary?  What's\nwrong with clearing the full line starting from column 1?\n\nAnyway, do you mean something like this?\n\n\ndiff --git a/sideband.c b/sideband.c\nindex ea7c25211e..5bfdd1d372 100644\n--- a/sideband.c\n+++ b/sideband.c\n@@ -120,7 +120,7 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)\n \n #define DISPLAY_PREFIX \"remote: \"\n \n-#define ANSI_SUFFIX \"\\033[K\"\n+#define ANSI_PREFIX \"\\033[K\"\n #define DUMB_SUFFIX \"        \"\n \n int demultiplex_sideband(const char *me, int status,\n@@ -129,15 +129,19 @@ int demultiplex_sideband(const char *me, int status,\n \t\t\t struct strbuf *scratch,\n \t\t\t enum sideband_type *sideband_type)\n {\n+\tstatic const char *prefix;\n \tstatic const char *suffix;\n \tconst char *b, *brk;\n \tint band;\n \n \tif (!suffix) {\n-\t\tif (isatty(2) && !is_terminal_dumb())\n-\t\t\tsuffix = ANSI_SUFFIX;\n-\t\telse\n+\t\tif (isatty(2) && !is_terminal_dumb()) {\n+\t\t\tprefix = DISPLAY_PREFIX ANSI_PREFIX;\n+\t\t\tsuffix = \"\";\n+\t\t} else {\n+\t\t\tprefix = DISPLAY_PREFIX;\n \t\t\tsuffix = DUMB_SUFFIX;\n+\t\t}\n \t}\n \n \tif (status == PACKET_READ_EOF) {\n@@ -172,7 +176,7 @@ int demultiplex_sideband(const char *me, int status,\n \t\tif (die_on_error)\n \t\t\tdie(_(\"remote error: %s\"), buf + 1);\n \t\tstrbuf_addf(scratch, \"%s%s\", scratch->len ? \"\\n\" : \"\",\n-\t\t\t    DISPLAY_PREFIX);\n+\t\t\t    prefix);\n \t\tmaybe_colorize_sideband(scratch, buf + 1, len);\n \n \t\t*sideband_type = SIDEBAND_REMOTE_ERROR;\n@@ -203,7 +207,7 @@ int demultiplex_sideband(const char *me, int status,\n \t\t\t\tstrbuf_addstr(scratch, suffix);\n \n \t\t\tif (!scratch->len)\n-\t\t\t\tstrbuf_addstr(scratch, DISPLAY_PREFIX);\n+\t\t\t\tstrbuf_addstr(scratch, prefix);\n \n \t\t\t/*\n \t\t\t * A use case that we should not add clear-to-eol suffix\n@@ -230,7 +234,7 @@ int demultiplex_sideband(const char *me, int status,\n \n \t\tif (*b) {\n \t\t\tstrbuf_addstr(scratch, scratch->len ?\n-\t\t\t\t    \"\" : DISPLAY_PREFIX);\n+\t\t\t\t    \"\" : prefix);\n \t\t\tmaybe_colorize_sideband(scratch, b, strlen(b));\n \t\t}\n \t\treturn 0;\n\n"},{"id":"542803","messageId":"CAHYJk3Q6xjW8mBvbQkN3vsDb2e9Em6PuDinFoTFwqkTXaKK=rQ@mail.gmail.com","threadId":"65590","inReplyTo":"3364c573-b7f4-4ec0-b471-312aa11028fe@web.de","subject":"Re: Git trims the last character of content from remotes","fromName":"Mikael Magnusson","fromEmail":"mikachu@gmail.com","sentAt":"2026-05-06T09:37:39Z","receivedAt":"2026-05-06T09:37:54Z","isPatch":false,"body":"On Tue, May 5, 2026 at 9:46 PM René Scharfe <l.s.r@web.de> wrote:\n>\n> On 5/5/26 2:34 AM, Chris Torek wrote:\n> > On Mon, May 4, 2026 at 10:02 AM Hugo Osvaldo Barrera <hugo@whynothugo.nl> wrote:\n> > [snippage]\n> >> When the width of a whole line is the same as my terminal width ...\n> > [snippage]\n> >> ... sideband.c prints ANSI_SUFFIX = \"\\033[K\", this escape\n> >> sequence being \"clear the line from the current position until the end of the\n> >> line\", and this is the root cause of the issue.\n>\n> > If you have a non-empty prefix\n> > string before this \"clear to end of line\" suffix, the solution is more\n> > obvious: print the ESC [ K as a *prefix* rather than a suffix, but\n> > that fails with the empty prefix.\n> We do have a non-empty prefix, but why would it be necessary?  What's\n> wrong with clearing the full line starting from column 1?\n>\n> Anyway, do you mean something like this?\n\nIf the purpose of the clear is to reset the background color on\nwrapped lines, this will not have any effect, since you clear before\nthe new line is wrapped in. (This is a bit of an obscure edge case, if\nyou set the background color, and wrap the line, the entire new line\nwill be scrolled in with the active background color, then you write\nperhaps 10 more characters and send the sequence to reset the\nbackground color, but the entire rest of the line is still brown, or\nwhatever it was set to when you wrapped).\n\nExample command to reproduce locally,\n% echo -e '\\e[43maaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\e[0mhihi'\n(Add more aaaaaaa if necessary so that the line breaks before they end).\n\n-- \nMikael Magnusson\n"},{"id":"542804","messageId":"CAHYJk3SW-JwWwk2h=vfDQ4udwQoW2TrmcntiPVwjUJSGiLU2wQ@mail.gmail.com","threadId":"65590","inReplyTo":"CAHYJk3Q6xjW8mBvbQkN3vsDb2e9Em6PuDinFoTFwqkTXaKK=rQ@mail.gmail.com","subject":"Re: Git trims the last character of content from remotes","fromName":"Mikael Magnusson","fromEmail":"mikachu@gmail.com","sentAt":"2026-05-06T09:40:47Z","receivedAt":"2026-05-06T09:41:03Z","isPatch":false,"body":"On Wed, May 6, 2026 at 11:37 AM Mikael Magnusson <mikachu@gmail.com> wrote:\n>\n> On Tue, May 5, 2026 at 9:46 PM René Scharfe <l.s.r@web.de> wrote:\n> >\n> > On 5/5/26 2:34 AM, Chris Torek wrote:\n> > > On Mon, May 4, 2026 at 10:02 AM Hugo Osvaldo Barrera <hugo@whynothugo.nl> wrote:\n> > > [snippage]\n> > >> When the width of a whole line is the same as my terminal width ...\n> > > [snippage]\n> > >> ... sideband.c prints ANSI_SUFFIX = \"\\033[K\", this escape\n> > >> sequence being \"clear the line from the current position until the end of the\n> > >> line\", and this is the root cause of the issue.\n> >\n> > > If you have a non-empty prefix\n> > > string before this \"clear to end of line\" suffix, the solution is more\n> > > obvious: print the ESC [ K as a *prefix* rather than a suffix, but\n> > > that fails with the empty prefix.\n> > We do have a non-empty prefix, but why would it be necessary?  What's\n> > wrong with clearing the full line starting from column 1?\n> >\n> > Anyway, do you mean something like this?\n>\n> If the purpose of the clear is to reset the background color on\n> wrapped lines, this will not have any effect, since you clear before\n> the new line is wrapped in. (This is a bit of an obscure edge case, if\n> you set the background color, and wrap the line, the entire new line\n> will be scrolled in with the active background color, then you write\n> perhaps 10 more characters and send the sequence to reset the\n> background color, but the entire rest of the line is still brown, or\n> whatever it was set to when you wrapped).\n>\n> Example command to reproduce locally,\n> % echo -e '\\e[43maaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\e[0mhihi'\n> (Add more aaaaaaa if necessary so that the line breaks before they end).\n\nSorry for the double post, but I forgot an important thing, this only\nhappens if you *actually* scroll in a new line, ie if you open a new\nterminal and run this, you won't see any problems until you get to the\nbottom of the screen.\n\n-- \nMikael Magnusson\n"},{"id":"542813","messageId":"4d8aa86f-160a-4f01-beaf-e3f011f875cf@web.de","threadId":"65590","inReplyTo":"CAHYJk3SW-JwWwk2h=vfDQ4udwQoW2TrmcntiPVwjUJSGiLU2wQ@mail.gmail.com","subject":"Re: Git trims the last character of content from remotes","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-05-06T16:00:04Z","receivedAt":"2026-05-06T16:00:19Z","isPatch":false,"body":"On 5/6/26 11:40 AM, Mikael Magnusson wrote:\n> On Wed, May 6, 2026 at 11:37 AM Mikael Magnusson <mikachu@gmail.com> wrote:\n>>\n>> On Tue, May 5, 2026 at 9:46 PM René Scharfe <l.s.r@web.de> wrote:\n>>>\n>>> On 5/5/26 2:34 AM, Chris Torek wrote:\n>>>> On Mon, May 4, 2026 at 10:02 AM Hugo Osvaldo Barrera <hugo@whynothugo.nl> wrote:\n>>>> [snippage]\n>>>>> When the width of a whole line is the same as my terminal width ...\n>>>> [snippage]\n>>>>> ... sideband.c prints ANSI_SUFFIX = \"\\033[K\", this escape\n>>>>> sequence being \"clear the line from the current position until the end of the\n>>>>> line\", and this is the root cause of the issue.\n>>>\n>>>> If you have a non-empty prefix\n>>>> string before this \"clear to end of line\" suffix, the solution is more\n>>>> obvious: print the ESC [ K as a *prefix* rather than a suffix, but\n>>>> that fails with the empty prefix.\n>>> We do have a non-empty prefix, but why would it be necessary?  What's\n>>> wrong with clearing the full line starting from column 1?\n>>>\n>>> Anyway, do you mean something like this?\n>>\n>> If the purpose of the clear is to reset the background color on\n>> wrapped lines, this will not have any effect, since you clear before\n>> the new line is wrapped in. (This is a bit of an obscure edge case, if\n>> you set the background color, and wrap the line, the entire new line\n>> will be scrolled in with the active background color, then you write\n>> perhaps 10 more characters and send the sequence to reset the\n>> background color, but the entire rest of the line is still brown, or\n>> whatever it was set to when you wrapped).\n>>\n>> Example command to reproduce locally,\n>> % echo -e '\\e[43maaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\e[0mhihi'\n>> (Add more aaaaaaa if necessary so that the line breaks before they end).\n> \n> Sorry for the double post, but I forgot an important thing, this only\n> happens if you *actually* scroll in a new line, ie if you open a new\n> terminal and run this, you won't see any problems until you get to the\n> bottom of the screen.\nThe purpose of clearing here is to avoid leaving local progress line\nremnants after the remote line.  Original discussion:\nhttps://lore.kernel.org/git/alpine.LFD.0.9999.0711032328490.21255@xanadu.home/\n\nYou're right that erasing before filling the whole line and then some\nis unnecessary.  But it wouldn't hurt, either, no?\n\nRené\n\n"},{"id":"542968","messageId":"9826dabf-c9a6-4397-8ae6-a24f9c507f1b@web.de","threadId":"65590","inReplyTo":"CAPx1Gvf5Vts3oS2BdFQ4PpCR-UY=5cYW7fgOkRuQpi8ug2JXDg@mail.gmail.com","subject":"[PATCH] sideband: clear full line when printing remote messages","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2026-05-10T12:42:04Z","receivedAt":"2026-05-10T12:42:19Z","isPatch":true,"body":"demultiplex_sideband() can write its remote output over active local\nprogress lines.  That's why it has been using ANSI code Erase in Line on\nsmart terminals to clear the remainder of lines it writes since\nebe8fa738d (fix display overlap between remote and local progress,\n2007-11-04).\n\nThis erases the last character of remote lines that span the full width\nof the terminal, though, as the cursor is stuck at the rightmost column\nfor them.  It's the same effect as in the following command, which\nclears the 1 and shows just the leading zeros:\n\n   $ EL=\"\\033[K\"\n   $ printf \"%0${COLUMNS}d${EL}\\n\" 1\n\nIf we move the ANSI code to the start we get to see the 1 as well:\n\n   $ printf \"${EL}%0${COLUMNS}d\\n\" 1\n\nSo do the same in demultiplex_sideband() and emit the ANSI code as a\nprefix instead of a suffix to show messages in full even if they happen\nto fill the whole width of a smart terminal.\n\nReported-by: Hugo Osvaldo Barrera <hugo@whynothugo.nl>\nSuggested-by: Chris Torek <chris.torek@gmail.com>\nSigned-off-by: René Scharfe <l.s.r@web.de>\n---\n sideband.c | 22 ++++++++++++----------\n 1 file changed, 12 insertions(+), 10 deletions(-)\n\ndiff --git a/sideband.c b/sideband.c\nindex ea7c25211e..48ed4c8099 100644\n--- a/sideband.c\n+++ b/sideband.c\n@@ -120,7 +120,7 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)\n \n #define DISPLAY_PREFIX \"remote: \"\n \n-#define ANSI_SUFFIX \"\\033[K\"\n+#define ANSI_PREFIX \"\\033[K\"\n #define DUMB_SUFFIX \"        \"\n \n int demultiplex_sideband(const char *me, int status,\n@@ -129,15 +129,18 @@ int demultiplex_sideband(const char *me, int status,\n \t\t\t struct strbuf *scratch,\n \t\t\t enum sideband_type *sideband_type)\n {\n-\tstatic const char *suffix;\n+\tstatic const char *prefix, *suffix;\n \tconst char *b, *brk;\n \tint band;\n \n \tif (!suffix) {\n-\t\tif (isatty(2) && !is_terminal_dumb())\n-\t\t\tsuffix = ANSI_SUFFIX;\n-\t\telse\n+\t\tif (isatty(2) && !is_terminal_dumb()) {\n+\t\t\tprefix = ANSI_PREFIX DISPLAY_PREFIX;\n+\t\t\tsuffix = \"\";\n+\t\t} else {\n+\t\t\tprefix = DISPLAY_PREFIX;\n \t\t\tsuffix = DUMB_SUFFIX;\n+\t\t}\n \t}\n \n \tif (status == PACKET_READ_EOF) {\n@@ -171,8 +174,7 @@ int demultiplex_sideband(const char *me, int status,\n \tcase 3:\n \t\tif (die_on_error)\n \t\t\tdie(_(\"remote error: %s\"), buf + 1);\n-\t\tstrbuf_addf(scratch, \"%s%s\", scratch->len ? \"\\n\" : \"\",\n-\t\t\t    DISPLAY_PREFIX);\n+\t\tstrbuf_addf(scratch, \"%s%s\", scratch->len ? \"\\n\" : \"\", prefix);\n \t\tmaybe_colorize_sideband(scratch, buf + 1, len);\n \n \t\t*sideband_type = SIDEBAND_REMOTE_ERROR;\n@@ -203,7 +205,7 @@ int demultiplex_sideband(const char *me, int status,\n \t\t\t\tstrbuf_addstr(scratch, suffix);\n \n \t\t\tif (!scratch->len)\n-\t\t\t\tstrbuf_addstr(scratch, DISPLAY_PREFIX);\n+\t\t\t\tstrbuf_addstr(scratch, prefix);\n \n \t\t\t/*\n \t\t\t * A use case that we should not add clear-to-eol suffix\n@@ -229,8 +231,8 @@ int demultiplex_sideband(const char *me, int status,\n \t\t}\n \n \t\tif (*b) {\n-\t\t\tstrbuf_addstr(scratch, scratch->len ?\n-\t\t\t\t    \"\" : DISPLAY_PREFIX);\n+\t\t\tif (!scratch->len)\n+\t\t\t\tstrbuf_addstr(scratch, prefix);\n \t\t\tmaybe_colorize_sideband(scratch, b, strlen(b));\n \t\t}\n \t\treturn 0;\n-- \n2.54.0\n"},{"id":"542980","messageId":"xmqqzf26971p.fsf@gitster.g","threadId":"65590","inReplyTo":"9826dabf-c9a6-4397-8ae6-a24f9c507f1b@web.de","subject":"Re: [PATCH] sideband: clear full line when printing remote messages","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-05-10T23:30:26Z","receivedAt":"2026-05-10T23:30:29Z","isPatch":true,"body":"René Scharfe <l.s.r@web.de> writes:\n\n> demultiplex_sideband() can write its remote output over active local\n> progress lines.  That's why it has been using ANSI code Erase in Line on\n> smart terminals to clear the remainder of lines it writes since\n> ebe8fa738d (fix display overlap between remote and local progress,\n> 2007-11-04).\n>\n> This erases the last character of remote lines that span the full width\n> of the terminal, though, as the cursor is stuck at the rightmost column\n> for them.  It's the same effect as in the following command, which\n> clears the 1 and shows just the leading zeros:\n>\n>    $ EL=\"\\033[K\"\n>    $ printf \"%0${COLUMNS}d${EL}\\n\" 1\n>\n> If we move the ANSI code to the start we get to see the 1 as well:\n>\n>    $ printf \"${EL}%0${COLUMNS}d\\n\" 1\n>\n> So do the same in demultiplex_sideband() and emit the ANSI code as a\n> prefix instead of a suffix to show messages in full even if they happen\n> to fill the whole width of a smart terminal.\n\nMakes sense.  The final objective is to make sure that leftover\nletters near the end of line printed by previous \"print\" would not\nremain after the material we are printing, so it does not matter if\nwe print and then erase the remainder or we erase the whole line and\nprint.  And the latter is an obvious way to make it easier to reason\nabout in the presense of funkiness in the ways terminals behave\naround the end of line.\n"},{"id":"549501","messageId":"xmqqldanyzh6.fsf@gitster.g","threadId":"65590","inReplyTo":"2d3f5504-f5dd-4171-96e8-b5633b6a1f5e@app.fastmail.com","subject":"Re: Git trims the last character of content from remotes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-08-03T15:51:01Z","receivedAt":"2026-08-03T15:51:04Z","isPatch":false,"body":"\"Hugo Osvaldo Barrera\" <hugo@whynothugo.nl> writes:\n\n> When piping to cat or to a file, this sequence is not printed, so the output is\n> fine.\n>\n> Is this a bug?\n\nPlease tell us more, if you are running Git 2.55 (or newer) and\nseeing the above behaviour.\n\nIt updated in 31e8fcabd8 (sideband: clear full line when printing\nremote messages, 2026-05-10) and was shipped in Git 2.55 on\n2026-06-29.\n"}]}