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

[PATCH 2/2] commit --amend: cope with missing display name

From
Jonathan Nieder <jrnieder@gmail.com>
Date
May 2, 2010, 08:57 UTC
Message-ID
<20100502085712.GB1767@progeny.tock>
In-Reply-To
<20100502084827.GA1690@progeny.tock>

Though I have not seen this in the wild, it has been said that there are likely to be git repositories converted from other version control systems with an invalid ident line like this one:

  author <user@example.com> 18746342 +0000

Because there is no space between the (empty) user name and the email address, commit --amend chokes. When searching for a space-left-bracket sequence on the ident line, it finds it in the committer line, ending up utterly confused.

Better for commit --amend to treat this like a valid ident line with empty username and complain.

The tests remove the questionable commit objects after use so there is no chance for them to confuse later tests.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Thanks for reading.  I look forward to your thoughts.
 builtin/commit.c  |   20 +++++++++++++-------
 t/t7509-commit.sh |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 7 deletions(-)
diff --git a/builtin/commit.c b/builtin/commit.c
index c5ab683..a3b6fc4 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -455,15 +455,21 @@ static void determine_author_info(void)
 		if (!a)
 			die("invalid commit: %s", use_message);
 
-		lb = strstr(a + 8, " <");
-		rb = strstr(a + 8, "> ");
-		eol = strchr(a + 8, '\n');
-		if (!lb || !rb || !eol)
+		lb = strchrnul(a + strlen("\nauthor "), '<');
+		rb = strchrnul(lb, '>');
+		eol = strchrnul(rb, '\n');
+		if (!*lb || !*rb || !*eol)
 			die("invalid commit: %s", use_message);
 
-		name = xstrndup(a + 8, lb - (a + 8));
-		email = xstrndup(lb + 2, rb - (lb + 2));
-		date = xstrndup(rb + 2, eol - (rb + 2));
+		if (lb == a + strlen("\nauthor "))
+			/* \nauthor <foo@example.com> */
+			name = xcalloc(1, 1);
+		else
+			name = xmemdupz(a + strlen("\nauthor "),
+			                (lb - strlen(" ") -
+			                 (a + strlen("\nauthor "))));
+		email = xmemdupz(lb + strlen("<"), rb - (lb + strlen("<")));
+		date = xmemdupz(rb + strlen("> "), eol - (rb + strlen("> ")));
 	}
 
 	if (force_author) {
diff --git a/t/t7509-commit.sh b/t/t7509-commit.sh
index d52c060..3ea33db 100755
--- a/t/t7509-commit.sh
+++ b/t/t7509-commit.sh
@@ -83,6 +83,52 @@ test_expect_success '--amend option copies authorship' '
 	test_cmp expect actual
 '
 
+sha1_file() {
+	echo "$*" | sed "s#..#.git/objects/&/#"
+}
+remove_object() {
+	rm -f $(sha1_file "$*")
+}
+no_reflog() {
+	cp .git/config .git/config.saved &&
+	echo "[core] logallrefupdates = false" >>.git/config &&
+	test_when_finished "mv -f .git/config.saved .git/config" &&
+
+	if test -e .git/logs
+	then
+		mv .git/logs . &&
+		test_when_finished "mv logs .git/"
+	fi
+}
+
+test_expect_success '--amend option with empty author' '
+	git cat-file commit Initial >tmp &&
+	sed "s/author [^<]* </author  </" tmp >empty-author &&
+	no_reflog &&
+	sha=$(git hash-object -t commit -w empty-author) &&
+	test_when_finished "remove_object $sha" &&
+	git checkout $sha &&
+	test_when_finished "git checkout Initial" &&
+	echo "Empty author test" >>foo &&
+	test_tick &&
+	! git commit -a -m "empty author" --amend 2>err &&
+	grep "empty ident" err
+'
+
+test_expect_success '--amend option with missing author' '
+	git cat-file commit Initial >tmp &&
+	sed "s/author [^<]* </author </" tmp >malformed &&
+	no_reflog &&
+	sha=$(git hash-object -t commit -w malformed) &&
+	test_when_finished "remove_object $sha" &&
+	git checkout $sha &&
+	test_when_finished "git checkout Initial" &&
+	echo "Missing author test" >>foo &&
+	test_tick &&
+	! git commit -a -m "malformed author" --amend 2>err &&
+	grep "empty ident" err
+'
+
 test_expect_success '--reset-author makes the commit ours even with --amend option' '
 	git checkout Initial &&
 	echo "Test 6" >>foo &&
-- 
1.7.1
Previous: Jonathan Nieder
Message 3 of 3 in “commit --amend and missing space in ident line”
  1. 0/2 commit --amend and missing space in ident lineJonathan Nieder, May 2, 2010
  2. 1/2 test-lib: Let tests specify commands to be run at end of testJonathan Nieder, May 2, 2010
  3. 2/2 commit --amend: cope with missing display nameJonathan Nieder, May 2, 2010

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.