From: Atousa Duprat Date: Wed, 31 May 2017 05:32:52 GMT Subject: Re: [Bug] git branch -v has problems with carriage returns Message-ID: 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 wrote: > 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' >>> # >> third)> >>> >>> 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));