Skip to contentSkip to conversation

git-notes: fix printing of multi-line notes

PATCH Superseded Tor Arne Vestbø 7 participants 17 messages Jun 15, 2016

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 git-notes: fix printing of multi-line notes

The line length was read from the same position every time, causing mangled output when printing notes with multiple lines.

Also, adding new-line manually for each line ensures that we get a new-line between commits, matching git-log for commits without notes.

---

This approach uses a msg pointer, but I started out with just using msg + msgoffset all over the place, so if that's a preferred way to do things I'm happy to provide an alternate patch.

Also, I'm guessing this printing should go into pretty.c at some point, so you can reference the notes as part of a custom pretty format. If so, this code could be converted to use helpers such as get_one_line().

This is my first patch to Git, so sorry if I messed something up :)

notes.c | 13 +++++++------

1 files changed, 7 insertions(+), 6 deletions(-)
notes.c +0 -0
index ad43a2e..bd73784 100644
@@ -110,8 +110,8 @@ void get_commit_notes(const struct commit *commit, struct strbuf *sb,
{
	static const char *utf8 = "utf-8";
	unsigned char *sha1;
-	char *msg;
-	unsigned long msgoffset, msglen;
+	char *msg, *msg_p;
+	unsigned long linelen, msglen;
	enum object_type type;

	if (!initialized) {

@@ -148,12 +148,13 @@ void get_commit_notes(const struct commit *commit, struct strbuf *sb,

	strbuf_addstr(sb, "\nNotes:\n");

- for (msgoffset = 0; msgoffset < msglen;) {
- int linelen = strchrnul(msg, '\n') - msg;
+ for (msg_p = msg; msg_p < msg + msglen; msg_p += linelen + 1) {
+ linelen = strchrnul(msg_p, '\n') - msg_p;

		strbuf_addstr(sb, "    ");
-		strbuf_add(sb, msg + msgoffset, linelen);
-		msgoffset += linelen;
+		strbuf_add(sb, msg_p, linelen);
+		strbuf_addch(sb, '\n');
	}
+
	free(msg);
}
Signature · 1 line
1.6.0.2.GIT
Acked-by on v1 1/1
#1 lore raw

Hi,

Quoted 9 lines · Tor Arne Vestbø

The line length was read from the same position every time, causing mangled output when printing notes with multiple lines.

Also, adding new-line manually for each line ensures that we get a new-line between commits, matching git-log for commits without notes.

---

Patch looks good, so

For extra browny points, you could add a test with multi-line notes.

Ciao,
Dscho

#2 lore raw
Quoted 9 lines · Johannes Schindelin
Quoted 7 lines · Tor Arne Vestbø

The line length was read from the same position every time, causing mangled output when printing notes with multiple lines.

Also, adding new-line manually for each line ensures that we get a new-line between commits, matching git-log for commits without notes.

Quoted 8 lines
Quoted 2 lines

---

Patch looks good, so

For extra browny points, you could add a test with multi-line notes.

Yeah, not just "extra", having tests is a good way to make sure a new feature like this evolves healthily.

Tor?

#3 lore raw

Hi,

Quoted 14 lines · Junio C Hamano
Quoted 12 lines · Johannes Schindelin
Quoted 9 lines · Tor Arne Vestbø

The line length was read from the same position every time, causing mangled output when printing notes with multiple lines.

Also, adding new-line manually for each line ensures that we get a new-line between commits, matching git-log for commits without notes.

---

Quoted 8 lines
Quoted 5 lines

Patch looks good, so

For extra browny points, you could add a test with multi-line notes.

Yeah, not just "extra", having tests is a good way to make sure a new feature like this evolves healthily.

Oh, and of course I meant "brownie"...

Ducks,
Dscho

#4 lore raw

PATCH 1/1 git-notes: add test case for multi-line notes

In reply to Junio C Hamano

The tests adds a third commit with a multi-line note. The output of git log -2 is then checked to see if the note lines are wrapped correctly, and that there's a line separator between the two commits.

Also, changed from using 'git diff' to test expect vs. output to use 'test_cmp', as I had problems getting correct results using the former.

---
t/t3301-notes.sh | 35 ++++++++++++++++++++++++++++++++---

1 files changed, 32 insertions(+), 3 deletions(-)
t/t3301-notes.sh +0 -0
index ba42c45..76bb6dd 100755
@@ -8,8 +8,8 @@ test_description='Test commit notes'

. ./test-lib.sh

cat > fake_editor.sh << \EOF
-echo "$MSG" > "$1"
-echo "$MSG" >& 2
+echo -e "$MSG" > "$1"
+echo -e "$MSG" >& 2
EOF
chmod a+x fake_editor.sh
VISUAL=./fake_editor.sh
@@ -59,7 +59,36 @@ EOF
test_expect_success 'show notes' '

	! (git cat-file commit HEAD | grep b1) &&
	git log -1 > output &&

- git diff expect output
+ test_cmp expect output
+'
+test_expect_success 'create multi-line notes (setup)' '
+ : > a3 &&
+ git add a3 &&
+ test_tick &&
+ git commit -m 3rd &&
+ MSG="b3\nc3c3c3c3\nd3d3d3" git notes edit
+
+'
+
+cat > expect-multiline << EOF
+commit 1584215f1d29c65e99c6c6848626553fdd07fd75 +Author: A U Thor <[email protected]>
+Date: Thu Apr 7 15:15:13 2005 -0700
+
+ 3rd
+
+Notes:

+    b3
+    c3c3c3c3
+    d3d3d3

+EOF
+
+echo >> expect-multiline
+cat expect >> expect-multiline
+
+test_expect_success 'show multi-line notes' '
+ git log -2 > output &&
+ test_cmp expect-multiline output
'

test_done

Signature · 1 line
1.6.0.2.GIT
#5 lore raw

Re: [PATCH next] git-notes: add test case for multi-line notes

Hi,

Quoted 6 lines · Tor Arne Vestbø

The tests adds a third commit with a multi-line note. The output of git log -2 is then checked to see if the note lines are wrapped correctly, and that there's a line separator between the two commits.

Also, changed from using 'git diff' to test expect vs. output to use 'test_cmp', as I had problems getting correct results using the former.

You could skip the part that you had problems, as the test_cmp is obviously the correct thing to do.

t/t3301-notes.sh

Quoted 12 lines
t/t3301-notes.sh +0 -0
index ba42c45..76bb6dd 100755
@@ -8,8 +8,8 @@ test_description='Test commit notes'

. ./test-lib.sh

cat > fake_editor.sh << \EOF

t/t3301-notes.sh +2 -2
-echo "$MSG" > "$1"
-echo "$MSG" >& 2
+echo -e "$MSG" > "$1"
+echo -e "$MSG" >& 2

I seem to recall that we had plenty of fun substituting "echo -e" with "printf" whenever it entered the repository (... again...), as some platforms -- ahem, macosx, ahem -- are a bit peculiar with such options.

So you might want to make sure no % is passed as "$MSG", and use printf instead.

t/t3301-notes.sh

Quoted 8 lines
t/t3301-notes.sh +8 -0
+test_expect_success 'create multi-line notes (setup)' '
+	: > a3 &&
+	git add a3 &&
+	test_tick &&
+	git commit -m 3rd &&
+	MSG="b3\nc3c3c3c3\nd3d3d3" git notes edit
+
+'

Minor style nit: maybe you want to have an empty line at the beginning, too...

Quoted 5 lines
t/t3301-notes.sh +5 -0
+cat > expect-multiline << EOF
+commit 1584215f1d29c65e99c6c6848626553fdd07fd75
+Author: A U Thor <[email protected]>
+Date:   Thu Apr 7 15:15:13 2005 -0700
+

t/t3301-notes.sh

Quoted 10 lines
t/t3301-notes.sh +10 -0
+    3rd
+
+Notes:
+    b3
+    c3c3c3c3
+    d3d3d3
+EOF
+
+echo >> expect-multiline
+cat expect >> expect-multiline

Yeah. My initial reaction was: "you could have that echo inside the cat <<EOF", but this is clearer. Except that you should make sure that nothing is printed (M$' echo outputs something if you pass no parameters); printf "\n" would be my choice.

Other than that, very good: ACK.

Ciao,
Dscho

#6 lore raw

PATCH v2 1/1 git-notes: add test case for multi-line notes

The tests adds a third commit with a multi-line note. The output of git log -2 is then checked to see if the note lines are wrapped correctly, and that there's a line separator between the two commits.

---

Thanks for the feedback Johannes! Here's an updated patch. I removed the blank line instead of adding another, as that's the current style of that file.

t/t3301-notes.sh | 35 ++++++++++++++++++++++++++++++++---

1 files changed, 32 insertions(+), 3 deletions(-)
t/t3301-notes.sh +0 -0
index ba42c45..e260d79 100755
@@ -8,8 +8,9 @@ test_description='Test commit notes'

. ./test-lib.sh

cat > fake_editor.sh << \EOF
-echo "$MSG" > "$1"
-echo "$MSG" >& 2
+MSG=${MSG//%/}
+printf "$MSG" > "$1"
+printf "$MSG" >& 2
EOF
chmod a+x fake_editor.sh
VISUAL=./fake_editor.sh
@@ -59,7 +60,35 @@ EOF
test_expect_success 'show notes' '

	! (git cat-file commit HEAD | grep b1) &&
	git log -1 > output &&

- git diff expect output
+ test_cmp expect output
+'
+test_expect_success 'create multi-line notes (setup)' '
+ : > a3 &&
+ git add a3 &&
+ test_tick &&
+ git commit -m 3rd &&
+ MSG="b3\nc3c3c3c3\nd3d3d3" git notes edit
+'
+
+cat > expect-multiline << EOF
+commit 1584215f1d29c65e99c6c6848626553fdd07fd75 +Author: A U Thor <[email protected]>
+Date: Thu Apr 7 15:15:13 2005 -0700
+
+ 3rd
+
+Notes:

+    b3
+    c3c3c3c3
+    d3d3d3

+EOF
+
+printf "\n" >> expect-multiline
+cat expect >> expect-multiline
+
+test_expect_success 'show multi-line notes' '
+ git log -2 > output &&
+ test_cmp expect-multiline output
'

test_done

Signature · 1 line
1.6.0.2.GIT
#7 lore raw

Re: [PATCH next v2] git-notes: add test case for multi-line notes

Review

Quoted 3 lines · Tor Arne Vestbø
(quoted diff) +3 -0
+MSG=${MSG//%/}
+printf "$MSG" > "$1"
+printf "$MSG" >& 2

Substitution parameter expansion is a bash-ism, IIRC. How about just

printf %s "$MSG" ?

-Peff

#8 lore raw

Re: [PATCH next v2] git-notes: add test case for multi-line notes

Quoted 6 lines · On Wednesday 2009 January 14 10:56:33 Jeff King wrote:

Review

Quoted 3 lines · Tor Arne Vestbø
(quoted diff) +3 -0
+MSG=${MSG//%/}
+printf "$MSG" > "$1"
+printf "$MSG" >& 2

Substitution parameter expansion is a bash-ism, IIRC. How about just

MSG=$(printf '%s\n' "$MSG" | sed -e 's/%/%%/g')
printf "$MSG" > "$1"
printf "$MSG" >& 2

Is my best attempt at portable and "safe". It's a few extra processes though.

Quoted 1 line

printf %s "$MSG" ?

On my box

$ printf '%s\n' '\n'
\n
$

He wants '\n' in $MSG to be expanded, and what you gave doesn't do that.

Signature · 4 lines
Boyd Stephen Smith Jr.                     ,= ,-_-. =. 
[email protected]                     ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy           `-'(. .)`-' 
http://iguanasuicide.net/                      \_/     
#9 lore raw

Re: [PATCH next v2] git-notes: add test case for multi-line notes

Quoted 8 lines · Boyd Stephen Smith Jr.
Quoted 1 line

printf %s "$MSG" ?

On my box

$ printf '%s\n' '\n'
\n
$

He wants '\n' in $MSG to be expanded, and what you gave doesn't do that.

Oh, sorry. That's what I get for not reading his patch carefully.

It looks like all of the input is statically included in the test script. While I think it is nice to be defensive, it is probably simplest to just assume there is no '%' in this case (which we can verify by reading the script).

-Peff

#10 lore raw

Re: [PATCH next v2] git-notes: add test case for multi-line notes

In reply to Jeff King
Quoted 9 lines · Jeff King

Review

Quoted 3 lines · Tor Arne Vestbø
(quoted diff) +3 -0
+MSG=${MSG//%/}
+printf "$MSG" > "$1"
+printf "$MSG" >& 2

Substitution parameter expansion is a bash-ism, IIRC. How about just

printf %s "$MSG" ?

A the point was that $MSG contains \n, which should be turned int LF. IMO, the easiest way to achieve this is:

MSG='b3
c3c3c3c3
d3d3d3'

test_expect_success ' ... ' '
...
MSG="$MSG" git notes edit
'

and go back to using echo in the part cited above.

-- Hannes

#11 lore raw

Re: [PATCH next v2] git-notes: add test case for multi-line notes

Quoted 7 lines · Johannes Sixt

A the point was that $MSG contains \n, which should be turned int LF. IMO, the easiest way to achieve this is:

MSG='b3
c3c3c3c3
d3d3d3'

Quoted 6 lines

test_expect_success ' ... ' '
...
MSG="$MSG" git notes edit
'

and go back to using echo in the part cited above.

Yes, sorry, I hadn't read his original patch carefully. I think that is a sane solution.

-Peff

#12 lore raw

PATCH v3 1/1 git-notes: add test case for multi-line notes

In reply to Johannes Sixt

The tests adds a third commit with a multi-line note. The output of git log -2 is then checked to see if the note lines are wrapped correctly, and that there's a line separator between the two commits.

---
t/t3301-notes.sh | 32 +++++++++++++++++++++++++++++++-

1 files changed, 31 insertions(+), 1 deletions(-)
t/t3301-notes.sh +0 -0
index ba42c45..9393a25 100755
@@ -59,7 +59,37 @@ EOF

test_expect_success 'show notes' '

	! (git cat-file commit HEAD | grep b1) &&
	git log -1 > output &&

- git diff expect output
+ test_cmp expect output
+'
+test_expect_success 'create multi-line notes (setup)' '
+ : > a3 &&
+ git add a3 &&
+ test_tick &&
+ git commit -m 3rd &&
+ MSG="b3
+c3c3c3c3
+d3d3d3" git notes edit
+'
+
+cat > expect-multiline << EOF
+commit 1584215f1d29c65e99c6c6848626553fdd07fd75 +Author: A U Thor <[email protected]>
+Date: Thu Apr 7 15:15:13 2005 -0700
+
+ 3rd
+
+Notes:

+    b3
+    c3c3c3c3
+    d3d3d3

+EOF
+
+printf "\n" >> expect-multiline
+cat expect >> expect-multiline
+
+test_expect_success 'show multi-line notes' '
+ git log -2 > output &&
+ test_cmp expect-multiline output
'

test_done

Signature · 1 line
1.6.0.2.GIT
Acked-by on v3 1/1
#13 lore raw

Re: [PATCH next v3] git-notes: add test case for multi-line notes

Hi,

Quoted 6 lines · Tor Arne Vestbø

The tests adds a third commit with a multi-line note. The output of git log -2 is then checked to see if the note lines are wrapped correctly, and that there's a line separator between the two commits.

---

Maybe squash the test into the fix?

Ciao,
Dscho

#14 lore raw

PATCH v4 1/1 git-notes: fix printing of multi-line notes

The line length was read from the same position every time, causing mangled output when printing notes with multiple lines.

Also, adding new-line manually for each line ensures that we get a new-line between commits, matching git-log for commits without notes.

Test case added to t3301-notes.sh.

---

Sorry about the delay. Here's a squashed patch.

notes.c          |   13 +++++++------
t/t3301-notes.sh |   32 +++++++++++++++++++++++++++++++-
2 files changed, 38 insertions(+), 7 deletions(-)
notes.c +0 -0
index ad43a2e..bd73784 100644
@@ -110,8 +110,8 @@ void get_commit_notes(const struct commit *commit, struct strbuf *sb,
{
	static const char *utf8 = "utf-8";
	unsigned char *sha1;
-	char *msg;
-	unsigned long msgoffset, msglen;
+	char *msg, *msg_p;
+	unsigned long linelen, msglen;
	enum object_type type;

	if (!initialized) {

@@ -148,12 +148,13 @@ void get_commit_notes(const struct commit *commit, struct strbuf *sb,

	strbuf_addstr(sb, "\nNotes:\n");

- for (msgoffset = 0; msgoffset < msglen;) {
- int linelen = strchrnul(msg, '\n') - msg;
+ for (msg_p = msg; msg_p < msg + msglen; msg_p += linelen + 1) {
+ linelen = strchrnul(msg_p, '\n') - msg_p;

		strbuf_addstr(sb, "    ");
-		strbuf_add(sb, msg + msgoffset, linelen);
-		msgoffset += linelen;
+		strbuf_add(sb, msg_p, linelen);
+		strbuf_addch(sb, '\n');
	}
+
	free(msg);
}
t/t3301-notes.sh +0 -0
index ba42c45..9393a25 100755
@@ -59,7 +59,37 @@ EOF

test_expect_success 'show notes' '

	! (git cat-file commit HEAD | grep b1) &&
	git log -1 > output &&

- git diff expect output
+ test_cmp expect output
+'
+test_expect_success 'create multi-line notes (setup)' '
+ : > a3 &&
+ git add a3 &&
+ test_tick &&
+ git commit -m 3rd &&
+ MSG="b3
+c3c3c3c3
+d3d3d3" git notes edit
+'
+
+cat > expect-multiline << EOF
+commit 1584215f1d29c65e99c6c6848626553fdd07fd75 +Author: A U Thor <[email protected]>
+Date: Thu Apr 7 15:15:13 2005 -0700
+
+ 3rd
+
+Notes:

+    b3
+    c3c3c3c3
+    d3d3d3

+EOF
+
+printf "\n" >> expect-multiline
+cat expect >> expect-multiline
+
+test_expect_success 'show multi-line notes' '
+ git log -2 > output &&
+ test_cmp expect-multiline output
'

test_done

Signature · 1 line
1.6.0.2.GIT
#15 lore raw
Quoted 7 lines · Tor Arne Vestbø

The line length was read from the same position every time, causing mangled output when printing notes with multiple lines.

Also, adding new-line manually for each line ensures that we get a new-line between commits, matching git-log for commits without notes.

Quoted 8 lines

Test case added to t3301-notes.sh.

---

Sorry about the delay. Here's a squashed patch.

Thanks. This exactly matches 22a3d06 (git-notes: fix printing of multi-line notes, 2009-01-13) I already have, so we are in a good shape.

#16 lore raw

Re: [PATCH next v2] git-notes: add test case for multi-line notes

In reply to Johannes Sixt

Hi,

Quoted 18 lines · Johannes Sixt
Quoted 9 lines · Jeff King

Review

Quoted 3 lines · Tor Arne Vestbø
(quoted diff) +3 -0
+MSG=${MSG//%/}
+printf "$MSG" > "$1"
+printf "$MSG" >& 2

Substitution parameter expansion is a bash-ism, IIRC. How about just

printf %s "$MSG" ?

A the point was that $MSG contains \n, which should be turned int LF. IMO, the easiest way to achieve this is:

MSG='b3
c3c3c3c3
d3d3d3'

Quoted 6 lines

test_expect_success ' ... ' '
...
MSG="$MSG" git notes edit
'

and go back to using echo in the part cited above.

Heh, I almost suggested it, but I know that I get quoting wrong all the time.

Ciao,
Dscho