git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [Bug] git branch -v has problems with carriage returns

From
Atousa Duprat <atousa.p@gmail.com>
Date
May 31, 2017, 05:32 UTC
Message-ID
<CA+izobteEUSisKXNr=k5BcN9hVV4nyqYPWuRLAgV-rg9chH4_g@mail.gmail.com>
In-Reply-To
<3d02b958-5f72-9676-bce9-afca962c07df@kdbg.org>
Here is my first attempt at fixing the issue.
There are two problems in ref-filter.c:

First, copy_subject() has been modified to turn '\n' into a space and every other ascii control character to be ignored.

Second, find_subpos() doesn't realize that a line that only contains a '\r\n' is a blank line – at least when using crlf convention. I have changed things so that a sequence of either '\n' or "\r\n" separate the subject from the body of the commit message. I am not looking at the crlf setting because it doesn't seem like a useful distinction – when one would we ever care for \r\n not to be a blank line? But it could be done...

Both fixes are minimal, but it feels like they are a issues with the specific encoding. Does git mandate ascii or utf-8 commit messages? If not, there may be a larger issue here with encodings and line-end conventions at the very least in ref-filter.c Guidance would be appreciated for how to deal with this issue...

Patch attached.
Atousa
On Fri, May 19, 2017 at 11:48 PM, Johannes Sixt <j6t@kdbg.org> wrote:
Show 36 quoted lines
> Am 19.05.2017 um 23:55 schrieb Atousa Duprat:
>>
>> I have tried to repro this issue but git goes out of its way to store
>> the commit messages using unix end-of-line format.
>> I think that git itself cannot create a repo exhibiting this problem.
>
>
> Here is a recipe to reproduce the error:
>
>   git init
>   git commit --allow-empty -m initial
>   git branch crlf $(printf '%s\r\n' subject '' line3_long line4 |
>        git commit-tree HEAD:)
>
> The reason for the "bug" is obviously that a line having CR in addition to
> LF is not "an empty line". Consequently, the second line is not treated as a
> separator between subject and body, whereupon Git concatenates all lines
> into one large subject line. This strips the LFs but leaves the CRs in tact,
> which, when printed on a terminal move the cursor to the beginning of the
> line, so that text after the CRs overwrites what is already in the terminal.
>
> This is just to give you a head start. I'm not going to look into this.
>
> -- Hannes
>
>
>>> If I do `git branch -v` with such a subject line somehow the third and
>>> second line get combined before the hash. Example:
>>>
>>> $ git branch -v
>>> See merge request !XXXX temp space 84e18d22fd Merge branch
>>> 'feature-XXX' into 'develop'
>>> # <begins with third line> <ending of seconds line (if longer than
>>> third)> <commit hash (correct)> <subject line (correct)>
>>>
>>> Before git v2.13.0 `git branch -v` worked completely normal.
diff --git a/ref-filter.c b/ref-filter.c
index 3a640448f..bc573f481 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -836,11 +836,15 @@ static const char *copy_email(const char *buf)
 static char *copy_subject(const char *buf, unsigned long len)
 {
 	char *r = xmemdupz(buf, len);
-	int i;
+	int i, j;
 
-	for (i = 0; i < len; i++)
+	for (i = 0, j = 0; i < len; i++, j++)
 		if (r[i] == '\n')
-			r[i] = ' ';
+			r[j] = ' ';
+		else if (r[i] < 32)
+                    j--; // skip ascii control characters that are not '\n'
+                else r[j] = r[i];
+        r[j]=0;
 
 	return r;
 }
@@ -956,9 +960,12 @@ static void find_subpos(const char *buf, unsigned long sz,
 			eol++;
 		buf = eol;
 	}
+
 	/* skip any empty lines */
 	while (*buf == '\n')
 		buf++;
+	while (*buf == '\r' && *(buf+1) == '\n')
+		buf += 2;
 
 	/* parse signature first; we might not even have a subject line */
 	*sig = buf + parse_signature(buf, strlen(buf));
Previous: Johannes SixtNext: Stefan Beller
Message 5 of 21 in “[Bug] git branch -v has problems with carriage returns”
  1. Animi VulpisMay 16, 2017
  2. Atousa DupratMay 19, 2017
  3. Animi VulpisMay 19, 2017
  4. Johannes SixtMay 20, 2017
  5. Atousa DupratMay 31, 2017
  6. Stefan BellerMay 31, 2017
  7. Junio C HamanoJun 1, 2017
  8. ref-filter: treat CRLF as same as LF in find_subposDOAN Tran Cong Danh, May 21, 2017
  9. Junio C HamanoMay 22, 2017
  10. DOAN Tran Cong DanhMay 22, 2017
  11. Jeff KingMay 22, 2017
  12. Junio C HamanoMay 23, 2017
  13. Junio C HamanoMay 23, 2017
  14. Junio C HamanoMay 23, 2017
  15. ref-filter: treat CRLF as same as LF in find_subposDOAN Tran Cong Danh, May 21, 2017
  16. ref-filter: trim end whitespace in subjectDOAN Tran Cong Danh, May 22, 2017
  17. ref-filter: trim end whitespace in subjectDOAN Tran Cong Danh, May 22, 2017
  18. Johannes SixtMay 22, 2017
  19. Jeff KingMay 22, 2017
  20. Johannes SixtMay 22, 2017
  21. Atousa DupratMay 19, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.