From: ĐOÀN Trần Công Danh <congdanhqx@xxxxxxxxx> Commit 949af0684 ("branch: use ref-filter printing APIs", 2017-01-10) make `git branch -v` stops trimming end-whitespace in subject, and it stops treating next all-whitespace-line as an empty line. Quote from git mailing-list: > 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 line 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. To recover previous behavior, trim all whitespace at the end of first line, and treat all-white-space line as empty line Reported-by: Animi Vulpis <animi.vulpis@xxxxxxxxx> Helped-by: Johannes Sixt <j6t@xxxxxxxx> Signed-off-by: ĐOÀN Trần Công Danh <congdanhqx@xxxxxxxxx> --- ref-filter.c | 21 +++++++++++++++++---- t/t3203-branch-output.sh | 3 ++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ref-filter.c b/ref-filter.c index 1fc5e9970..3625d543c 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -942,6 +942,17 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru } } +/* + * check if line in range [start, end) is a blank line or not + * data in range [start, end) must be valid before calling this function + */ +static int is_blank_line(const char *start, const char *end) +{ + while (start != end && isspace(*start)) + ++start; + return start == end; +} + static void find_subpos(const char *buf, unsigned long sz, const char **sub, unsigned long *sublen, const char **body, unsigned long *bodylen, @@ -967,19 +978,21 @@ static void find_subpos(const char *buf, unsigned long sz, /* subject is first non-empty line */ *sub = buf; /* subject goes to first empty line */ - while (buf < *sig && *buf && *buf != '\n') { + while (buf < *sig) { eol = strchrnul(buf, '\n'); if (*eol) eol++; + if (is_blank_line(buf, eol)) + break; buf = eol; } *sublen = buf - *sub; - /* drop trailing newline, if present */ - if (*sublen && (*sub)[*sublen - 1] == '\n') + /* drop trailing whitespace, if present */ + while (*sublen && isspace((*sub)[*sublen - 1])) *sublen -= 1; /* skip any empty lines */ - while (*buf == '\n') + while (isspace(*buf)) buf++; *body = buf; *bodylen = strlen(buf); diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh index 5778c0afe..fa4441868 100755 --- a/t/t3203-branch-output.sh +++ b/t/t3203-branch-output.sh @@ -13,7 +13,8 @@ test_expect_success 'make commits' ' test_expect_success 'make branches' ' git branch branch-one && - git branch branch-two HEAD^ + git branch branch-two $(printf "%s\r\n" one " " line3_long line4 | + git commit-tree HEAD:) ' test_expect_success 'make remote branches' ' -- 2.13.0.67.g10c78a1