{"thread":{"id":"63886","subject":"[PATCH] interactive: do strip trailing CRLF from input","startedAt":"2025-07-31T16:07:39Z","lastAt":"2025-07-31T16:37:12Z","messageCount":2,"participants":["Johannes Sixt","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"523110","messageId":"2295f183-038c-4751-b04d-0f1819b67b3a@kdbg.org","threadId":"63886","inReplyTo":null,"subject":"[PATCH] interactive: do strip trailing CRLF from input","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2025-07-31T16:07:36Z","receivedAt":"2025-07-31T16:07:39Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"`git reset -p file` on a Windows CMD refuses to do anything useful\nwith this error message:\n\n    (1/5) Unstage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? n\n    'nly one letter is expected, got 'n\n\nThe letter 'O' at the beginning of the line is overwritten by an\napostrophe, so, clearly the parser sees the string \"n\\r\".\n\nstrbuf_trim_trailing_newline() removes trailing CRLF from the string.\nIn particular, it first removes LF if present, and if that was the\ncase, it also removes CR if present.\n\ngit_read_line_interactively() clearly intends to remove CRLF as it\ncalls strbuf_trim_trailing_newline(). However, input is gathered using\nstrbuf_getline_lf(), which already removes the trailing LF. Now\nstrbuf_trim_trailing_newline() does not see LF, so that it does not\nremove CR, either, and leaves it for the caller to process.\n\nCall strbuf_getline() instead, which removes both LF and CR.\n\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n prompt.c | 8 +-------\n 1 file changed, 1 insertion(+), 7 deletions(-)\n\ndiff --git a/prompt.c b/prompt.c\nindex f21c5bf1c7..706fba2a50 100644\n--- a/prompt.c\n+++ b/prompt.c\n@@ -77,12 +77,6 @@ char *git_prompt(const char *prompt, int flags)\n \n int git_read_line_interactively(struct strbuf *line)\n {\n-\tint ret;\n-\n \tfflush(stdout);\n-\tret = strbuf_getline_lf(line, stdin);\n-\tif (ret != EOF)\n-\t\tstrbuf_trim_trailing_newline(line);\n-\n-\treturn ret;\n+\treturn strbuf_getline(line, stdin);\n }\n-- \n2.50.1.665.g4c0a7305c7\n"},{"id":"523111","messageId":"xmqqbjp0s4eh.fsf@gitster.g","threadId":"63886","inReplyTo":"2295f183-038c-4751-b04d-0f1819b67b3a@kdbg.org","subject":"Re: [PATCH] interactive: do strip trailing CRLF from input","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-07-31T16:37:10Z","receivedAt":"2025-07-31T16:37:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j6t@kdbg.org> writes:\n\n> `git reset -p file` on a Windows CMD refuses to do anything useful\n> with this error message:\n>\n>     (1/5) Unstage this hunk [y,n,q,a,d,j,J,g,/,e,p,?]? n\n>     'nly one letter is expected, got 'n\n>\n> The letter 'O' at the beginning of the line is overwritten by an\n> apostrophe, so, clearly the parser sees the string \"n\\r\".\n>\n> strbuf_trim_trailing_newline() removes trailing CRLF from the string.\n> In particular, it first removes LF if present, and if that was the\n> case, it also removes CR if present.\n>\n> git_read_line_interactively() clearly intends to remove CRLF as it\n> calls strbuf_trim_trailing_newline(). However, input is gathered using\n> strbuf_getline_lf(), which already removes the trailing LF. Now\n> strbuf_trim_trailing_newline() does not see LF, so that it does not\n> remove CR, either, and leaves it for the caller to process.\n>\n> Call strbuf_getline() instead, which removes both LF and CR.\n\nI was looking at vicinity of the code this morning, so I am more\nfamiliar with this codepath than I usually am ;-)\n\nThe above explanation makes perfect sense.  It is quite an old piece\nof code, and I am kind of surprised that nobody complained for the\npast 5 years.\n\nWill queue.  Thanks.\n\n>\n> Signed-off-by: Johannes Sixt <j6t@kdbg.org>\n> ---\n>  prompt.c | 8 +-------\n>  1 file changed, 1 insertion(+), 7 deletions(-)\n>\n> diff --git a/prompt.c b/prompt.c\n> index f21c5bf1c7..706fba2a50 100644\n> --- a/prompt.c\n> +++ b/prompt.c\n> @@ -77,12 +77,6 @@ char *git_prompt(const char *prompt, int flags)\n>  \n>  int git_read_line_interactively(struct strbuf *line)\n>  {\n> -\tint ret;\n> -\n>  \tfflush(stdout);\n> -\tret = strbuf_getline_lf(line, stdin);\n> -\tif (ret != EOF)\n> -\t\tstrbuf_trim_trailing_newline(line);\n> -\n> -\treturn ret;\n> +\treturn strbuf_getline(line, stdin);\n>  }\n"}]}