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

[PATCH] ref-filter: treat CRLF as same as LF in find_subpos

From
DOAN Tran Cong Danh <congdanhqx@gmail.com>
Date
May 21, 2017, 13:42 UTC
Message-ID
<20170521134209.25659-1-congdanhqx@gmail.com>
In-Reply-To
<CA+izobvwRCwGEtpCbey=gFbCh9sHBb5xB1i1LpMG0JCUy0O2mQ@mail.gmail.com>

Starting from commit 949af06 (branch: use ref-filter printing APIs, 2017-01-10), `git branch -v` doesn't treat CRLF as line separator anymore.

Quote from git mailing-list:
Show 13 quoted lines
> 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.
Reported-by: Animi Vulpis <animi.vulpis@gmail.com>
Helped-by: Johannes Sixt <j6t@kbdg.org>
Signed-off-by: DOAN Tran Cong Danh <congdanhqx@gmail.com>
---
 ref-filter.c             | 19 +++++++++++++++----
 t/t3203-branch-output.sh |  3 ++-
 2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/ref-filter.c b/ref-filter.c
index 1fc5e9970..b3c2276a5 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -967,7 +967,8 @@ 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 && *buf && *buf != '\n'
+	       && !(*buf == '\r' && *(buf + 1) == '\n')) {
 		eol = strchrnul(buf, '\n');
 		if (*eol)
 			eol++;
@@ -975,12 +976,22 @@ static void find_subpos(const char *buf, unsigned long sz,
 	}
 	*sublen = buf - *sub;
 	/* drop trailing newline, if present */
-	if (*sublen && (*sub)[*sublen - 1] == '\n')
+	if (*sublen && (*sub)[*sublen - 1] == '\n') {
 		*sublen -= 1;
+		/* also drop trailing CR before that LF */
+		if ((*sublen) && (*sub)[*sublen - 1] == '\r')
+			*sublen -= 1;
+	}
 
 	/* skip any empty lines */
-	while (*buf == '\n')
-		buf++;
+	while (1) {
+		if (*buf == '\n')
+			buf++;
+		else if (*buf == '\r' && *(buf + 1) == '\n')
+			buf += 2;
+		else
+			break;
+	}
 	*body = buf;
 	*bodylen = strlen(buf);
 	*nonsiglen = *sig - buf;
diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh
index 5778c0afe..29b392066 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
Previous: Junio C HamanoNext: Junio C Hamano
Message 8 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.