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

[PATCH v3] sequencer: add newline before adding footers

From
JTJonathan Tan <jonathantanmy@google.com>
Date
Apr 26, 2017, 20:50 UTC
Message-ID
<20170426205003.30825-1-jonathantanmy@google.com>
In-Reply-To
<20170425190651.8910-1-jonathantanmy@google.com>

When encountering a commit message that does not end in a newline, sequencer does not complete the line before determining if a blank line should be added. This causes the "(cherry picked..." and sign-off lines to sometimes appear on the same line as the last line of the commit message.

This behavior was introduced by commit 967dfd4 ("sequencer: use trailer's trailer layout", 2016-11-29). However, a revert of that commit would not resolve this issue completely: prior to that commit, a conforming footer was deemed to be non-conforming by has_conforming_footer() if there was no terminating newline, resulting in both conforming and non-conforming footers being treated the same when they should not be.

Resolve this issue, both for conforming and non-conforming footers, and in both do_pick_commit() and append_signoff(), by always adding a newline to the commit message if it does not end in one before checking the footer for conformity.

Reported-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
---

The failure in the case of non-footers not being terminated by a newline turns out to be quite easy to fix, so I've added that fix here. I think this makes the overall fix more obvious too.

I've used Jonathan Nieder's and Dscho's suggestions for the tests (except for --format vs --pretty, since --format seems to add an extra newline to the output).

 sequencer.c              | 11 ++++-------
 t/t3511-cherry-pick-x.sh | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 7 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 77afecaeb..ffac95545 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -1045,6 +1045,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
 			strbuf_addstr(&msgbuf, p);
 
 		if (opts->record_origin) {
+			strbuf_complete_line(&msgbuf);
 			if (!has_conforming_footer(&msgbuf, NULL, 0))
 				strbuf_addch(&msgbuf, '\n');
 			strbuf_addstr(&msgbuf, cherry_picked_prefix);
@@ -2335,6 +2336,9 @@ void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
 				getenv("GIT_COMMITTER_EMAIL")));
 	strbuf_addch(&sob, '\n');
 
+	if (!ignore_footer)
+		strbuf_complete_line(msgbuf);
+
 	/*
 	 * If the whole message buffer is equal to the sob, pretend that we
 	 * found a conforming footer with a matching sob
@@ -2355,13 +2359,6 @@ void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
 			 * the title and body to be filled in by the user.
 			 */
 			append_newlines = "\n\n";
-		} else if (msgbuf->buf[len - 1] != '\n') {
-			/*
-			 * Incomplete line.  Complete the line and add a
-			 * blank one so that there is an empty line between
-			 * the message body and the sob.
-			 */
-			append_newlines = "\n\n";
 		} else if (len == 1) {
 			/*
 			 * Buffer contains a single newline.  Add another
diff --git a/t/t3511-cherry-pick-x.sh b/t/t3511-cherry-pick-x.sh
index bf0a5c988..9888bf34b 100755
--- a/t/t3511-cherry-pick-x.sh
+++ b/t/t3511-cherry-pick-x.sh
@@ -208,6 +208,50 @@ test_expect_success 'cherry-pick -x -s adds sob even when trailing sob exists fo
 	test_cmp expect actual
 '
 
+test_expect_success 'cherry-pick -x handles commits with no NL at end of message' '
+	pristine_detach initial &&
+	printf "title\n\nSigned-off-by: A <a@example.com>" >msg &&
+	sha1=$(git commit-tree -p initial mesg-with-footer^{tree} <msg) &&
+	git cherry-pick -x $sha1 &&
+	git log -1 --pretty=format:%B >actual &&
+
+	printf "\n(cherry picked from commit %s)\n" $sha1 >>msg &&
+	test_cmp msg actual
+'
+
+test_expect_success 'cherry-pick -x handles commits with no footer and no NL at end of message' '
+	pristine_detach initial &&
+	printf "title\n\nnot a footer" >msg &&
+	sha1=$(git commit-tree -p initial mesg-with-footer^{tree} <msg) &&
+	git cherry-pick -x $sha1 &&
+	git log -1 --pretty=format:%B >actual &&
+
+	printf "\n\n(cherry picked from commit %s)\n" $sha1 >>msg &&
+	test_cmp msg actual
+'
+
+test_expect_success 'cherry-pick -s handles commits with no NL at end of message' '
+	pristine_detach initial &&
+	printf "title\n\nSigned-off-by: A <a@example.com>" >msg &&
+	sha1=$(git commit-tree -p initial mesg-with-footer^{tree} <msg) &&
+	git cherry-pick -s $sha1 &&
+	git log -1 --pretty=format:%B >actual &&
+
+	printf "\nSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n" >>msg &&
+	test_cmp msg actual
+'
+
+test_expect_success 'cherry-pick -s handles commits with no footer and no NL at end of message' '
+	pristine_detach initial &&
+	printf "title\n\nnot a footer" >msg &&
+	sha1=$(git commit-tree -p initial mesg-with-footer^{tree} <msg) &&
+	git cherry-pick -s $sha1 &&
+	git log -1 --pretty=format:%B >actual &&
+
+	printf "\n\nSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n" >>msg &&
+	test_cmp msg actual
+'
+
 test_expect_success 'cherry-pick -x treats "(cherry picked from..." line as part of footer' '
 	pristine_detach initial &&
 	sha1=$(git rev-parse mesg-with-cherry-footer^0) &&
-- 
2.13.0.rc0.306.g87b477812d-goog
Previous: Johannes Schindelin
Message 18 of 18 in “[GIT 2.12.2 REGRESSION] git cherry-pick -x”
  1. Brian NorrisApr 21, 2017
  2. Stefan BellerApr 21, 2017
  3. Jeff KingApr 21, 2017
  4. sequencer: require trailing NL in footersJonathan Tan, Apr 25, 2017
  5. Stefan BellerApr 25, 2017
  6. Jonathan TanApr 25, 2017
  7. Stefan BellerApr 25, 2017
  8. Johannes SchindelinApr 25, 2017
  9. Jonathan NiederApr 25, 2017
  10. Brian NorrisApr 25, 2017
  11. Brian NorrisApr 26, 2017
  12. Johannes SchindelinApr 25, 2017
  13. Jonathan NiederApr 25, 2017
  14. sequencer: require trailing NL in footersJonathan Tan, Apr 25, 2017
  15. Jonathan NiederApr 26, 2017
  16. Junio C HamanoApr 26, 2017
  17. Johannes SchindelinApr 26, 2017
  18. sequencer: add newline before adding footersJonathan Tan, Apr 26, 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.